Android實(shí)現(xiàn)GridView中的item自由拖動(dòng)效果
之前的工作中,需要實(shí)現(xiàn)一個(gè)功能就是GridView中的item可以自由拖動(dòng), 思考了一下,其實(shí)實(shí)現(xiàn)起來不是很困難,主要工作就是交換節(jié)點(diǎn),以及拖動(dòng)時(shí)的移動(dòng)效果,下面講講具體的實(shí)現(xiàn):
首先聲明一個(gè)BaseAdapter:
package com.dafasoft.dragablegridview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; import android.widget.BaseAdapter; import java.util.ArrayList; import java.util.List; /** * Created by zhangyulong on 16/9/22. */ public abstract class BaseDragableAdapter<T> extends BaseAdapter { protected List<T> mList; protected Context mContext; protected LayoutInflater mInflater; //初始化需隱藏的位置信息 protected int mHidePosition = AdapterView.INVALID_POSITION; public BaseDragableAdapter(Context context) { this.mContext = context; this.mInflater = LayoutInflater.from(context); mList = new ArrayList<T>(); } @Override public int getCount() { return mList == null ? 0 : mList.size(); } @Override public Object getItem(int i) { return mList == null ? 0 : mList.get(i); } @Override public long getItemId(int i) { return i; } @Override public abstract View getView(int i, View view, ViewGroup viewGroup); public void setList(List<T> list) { if (this.mList != null) this.mList.clear(); // 避免臟數(shù)據(jù) if (list == null) { return; } this.mList = list; } public void setList(T[] list){ ArrayList<T> arrayList = new ArrayList<T>(list.length); for (T t : list) { arrayList.add(t); } setList(arrayList); } public List<T> getList() { return this.mList; } public void addAll(List<T> list) { if (list == null || list.size() == 0) return; this.mList.addAll(list); } public void addAll(int location, List<T> list) { if (list == null || list.size() == 0) return; this.mList.addAll(location, list); } public void clean() { if (getCount() == 0) return; mList.clear(); } public void hideView(int position){ mHidePosition = position; notifyDataSetChanged(); } public void showHideView(){ //重置hideposition mHidePosition = AdapterView.INVALID_POSITION; notifyDataSetChanged(); } /** * 交換節(jié)點(diǎn) * @param draggedPos 拖拽的起始節(jié)點(diǎn) * @param currentPos 拖拽的當(dāng)前節(jié)點(diǎn) */ public void swapView(int draggedPos , int currentPos) { //從前往后拖 if(draggedPos < currentPos){ //將被拖拽的節(jié)點(diǎn)移動(dòng)至當(dāng)前節(jié)點(diǎn) mList.add(currentPos + 1 , mList.get(draggedPos)); //刪除拖拽前的節(jié)點(diǎn) mList.remove(draggedPos); } //從后往前拖 else if (draggedPos > currentPos) { //將被拖拽的節(jié)點(diǎn)移動(dòng)至當(dāng)前節(jié)點(diǎn) mList.add(currentPos , mList.get(draggedPos)); //刪除拖拽前的節(jié)點(diǎn) mList.remove(draggedPos + 1); } mHidePosition = currentPos; notifyDataSetChanged(); } }
其次實(shí)現(xiàn)DragableGridView:
package com.dafasoft.dragablegridview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.GridView; import android.widget.ImageView; /** * Created by zhangyulong on 16/9/22. */ public class DragableGridView extends GridView { private static final int DRAG_IMG_SHOW = 1; private static final int DRAG_IMG_NOT_SHOW = 0; private static final String LOG_TAG = "DragGridView"; private static final float AMP_FACTOR = 1.2f; private ImageView dragImageView; private WindowManager.LayoutParams dragImageViewParams; private WindowManager windowManager; private boolean isViewOnDrag = false; /**previous dragged over position*/ private int preDraggedOverPositon = AdapterView.INVALID_POSITION; private int downRawX; private int downRawY; public DragableGridView(Context context) { super(context); initView(); } public DragableGridView(Context context, AttributeSet attrs) { super(context, attrs); initView(); } public DragableGridView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initView(); } public void initView() { setOnItemLongClickListener(mOnItemLongClickListener); //setOnItemClickListener(onItemClickListener); //setOnItemSelectedListener(onItemSelectedListener); //初始化顯示被拖動(dòng)item的image view dragImageView = new ImageView(getContext()); dragImageView.setTag(DRAG_IMG_NOT_SHOW); //初始化用于設(shè)置dragImageView的參數(shù)對(duì)象 dragImageViewParams = new WindowManager.LayoutParams(); //獲取窗口管理對(duì)象,用于后面向窗口中添加dragImageView windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); } private OnItemLongClickListener mOnItemLongClickListener = new OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { //記錄長按item位置 preDraggedOverPositon = position; //獲取被長按item的drawing cache view.destroyDrawingCache(); view.setDrawingCacheEnabled(true); //通過被長按item,獲取拖動(dòng)item的bitmap Bitmap dragBitmap = Bitmap.createBitmap(view.getDrawingCache()); //設(shè)置拖動(dòng)item的參數(shù) dragImageViewParams.gravity = Gravity.TOP | Gravity.LEFT; //設(shè)置拖動(dòng)item為原item 1.2倍 dragImageViewParams.width = (int)(AMP_FACTOR*dragBitmap.getWidth()); dragImageViewParams.height = (int)(AMP_FACTOR*dragBitmap.getHeight()); //設(shè)置觸摸點(diǎn)為繪制拖動(dòng)item的中心 dragImageViewParams.x = (downRawX - dragImageViewParams.width/2); dragImageViewParams.y = (downRawY - dragImageViewParams.height/2); dragImageViewParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; //設(shè)置窗口支持透明度 dragImageViewParams.format = PixelFormat.TRANSLUCENT; dragImageViewParams.windowAnimations = 0; //dragImageView為被拖動(dòng)item的容器,清空上一次的顯示 if((int)dragImageView.getTag() == DRAG_IMG_SHOW) { windowManager.removeView(dragImageView); dragImageView.setTag(DRAG_IMG_NOT_SHOW); } //設(shè)置本次被長按的item dragImageView.setImageBitmap(dragBitmap); //添加拖動(dòng)item到屏幕 windowManager.addView(dragImageView, dragImageViewParams); dragImageView.setTag(DRAG_IMG_SHOW); isViewOnDrag = true; //設(shè)置被長按item不顯示 ((BaseDragableAdapter)getAdapter()).hideView(position); return true; } }; @Override public boolean onTouchEvent(MotionEvent ev) { //被按下時(shí)記錄按下的坐標(biāo) if(ev.getAction() == MotionEvent.ACTION_DOWN) { //獲取觸摸點(diǎn)相對(duì)于屏幕的坐標(biāo) downRawX = (int)ev.getRawX(); downRawY = (int)ev.getRawY(); } //dragImageView處于被拖動(dòng)時(shí),更新dragImageView位置 else if((ev.getAction() == MotionEvent.ACTION_MOVE) && (isViewOnDrag == true)) { Log.i(LOG_TAG, "" + ev.getRawX() + " " + ev.getRawY()); //設(shè)置觸摸點(diǎn)為dragImageView中心 dragImageViewParams.x = (int)(ev.getRawX() - dragImageView.getWidth()/2); dragImageViewParams.y = (int)(ev.getRawY() - dragImageView.getHeight()/2); //更新窗口顯示,移動(dòng)dragImageView的位置 windowManager.updateViewLayout(dragImageView, dragImageViewParams); //獲取當(dāng)前觸摸點(diǎn)的item position int currDraggedPosition = pointToPosition((int)ev.getX(), (int)ev.getY()); //如果當(dāng)前停留位置item不等于上次停留位置的item,交換本次和上次停留的item if((currDraggedPosition != AdapterView.INVALID_POSITION) && (currDraggedPosition != preDraggedOverPositon)) { ((BaseDragableAdapter)getAdapter()).swapView(preDraggedOverPositon, currDraggedPosition); preDraggedOverPositon = currDraggedPosition; } } //釋放dragImageView else if((ev.getAction() == MotionEvent.ACTION_UP) && (isViewOnDrag == true)) { ((BaseDragableAdapter)getAdapter()).showHideView(); if((int)dragImageView.getTag() == DRAG_IMG_SHOW) { windowManager.removeView(dragImageView); dragImageView.setTag(DRAG_IMG_NOT_SHOW); } isViewOnDrag = false; } return super.onTouchEvent(ev); } }
實(shí)現(xiàn)一個(gè)adapter繼承自BaseDragableAdapter:
package com.dafasoft.dragablegridview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * Created by zhangyulong on 16/9/22. */ public class MyAdapter extends BaseDragableAdapter<String> { public MyAdapter(Context context) { super(context); } @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder viewHolder; if (view == null) { viewHolder = new ViewHolder(); view = mInflater.inflate(R.layout.adapter_my , null); viewHolder.mItemTv = (TextView) view.findViewById(R.id.tv_item); view.setTag(viewHolder); } else { viewHolder = (ViewHolder)view.getTag(); } if (mHidePosition == i) { view.setVisibility(View.GONE); } else { view.setVisibility(View.VISIBLE); } viewHolder.mItemTv.setText(mList.get(i)); return view; } class ViewHolder{ TextView mItemTv; } }
在activity中使用:
package com.dafasoft.dragablegridview; import android.app.Activity; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import java.util.ArrayList; import java.util.List; public class MainActivity extends Activity { private DragableGridView mDragableGv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mDragableGv = (DragableGridView) findViewById(R.id.drag_grid_view); MyAdapter adapter = new MyAdapter(this); List<String> list = new ArrayList<String>(); for (int i = 0 ; i < 30 ; i ++) { list.add("position" + i); } adapter.setList(list); mDragableGv.setAdapter(adapter); } }
以上所述是小編給大家介紹的Android實(shí)現(xiàn)GridView中的item自由拖動(dòng)效果,實(shí)現(xiàn)一個(gè)模擬后臺(tái)數(shù)據(jù)登入的效果,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
- Android實(shí)現(xiàn)單頁面浮層可拖動(dòng)view的一種方法
- Android實(shí)現(xiàn)單頁面浮層可拖動(dòng)view的示例代碼
- Android自定義View圓形和拖動(dòng)圓、跟隨手指拖動(dòng)效果
- Android ViewDragHelper仿淘寶拖動(dòng)加載效果
- Android實(shí)現(xiàn)跟隨手指拖動(dòng)并自動(dòng)貼邊的View樣式(實(shí)例demo)
- Android實(shí)現(xiàn)ImageView圖片縮放和拖動(dòng)
- Android通過自定義ImageView控件實(shí)現(xiàn)圖片的縮放和拖動(dòng)的實(shí)現(xiàn)代碼
- Android RecyclerView滑動(dòng)刪除和拖動(dòng)排序
- Android自定義View實(shí)現(xiàn)拖動(dòng)選擇按鈕
- Android自定義View圓形和拖動(dòng)圓跟隨手指拖動(dòng)
相關(guān)文章
Android自定義View葉子旋轉(zhuǎn)完整版(六)
這篇文章主要為大家詳細(xì)介紹了Android自定義View葉子旋轉(zhuǎn)完整版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android開發(fā)實(shí)現(xiàn)錄屏小功能
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)錄屏小功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07Android編程設(shè)定activity進(jìn)入和退出效果的方法
這篇文章主要介紹了Android編程設(shè)定activity進(jìn)入和退出效果的方法,簡單分析了Android Activity進(jìn)入與退出效果的實(shí)現(xiàn)原理及相關(guān)屬性設(shè)置技巧,需要的朋友可以參考下2017-07-07Android自定義谷歌風(fēng)格ProgressBar
這篇文章主要為大家詳細(xì)介紹了Android自定義谷歌風(fēng)格ProgressBar的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Android搜索結(jié)果顯示高亮實(shí)例(有數(shù)據(jù)滑動(dòng)底部自動(dòng)刷新)
本篇文章主要介紹了Android搜索結(jié)果顯示高亮實(shí)例(有數(shù)據(jù)滑動(dòng)底部自動(dòng)刷新),非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-04-04