之前的工作中,需要实现一个功能就是GridView中的item可以自由拖动, 思考了一下,其实实现起来不是很困难,主要工作就是交换节点,以及拖动时的移动效果,下面讲讲具体的实现:
首先声明一个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; public abstract class baseDragableAdapterextends baseAdapter { protected List 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 (); } @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 list) { if (this.mList != null) this.mList.clear(); // 避免脏数据 if (list == null) { return; } this.mList = list; } public void setList(T[] list){ ArrayList arrayList = new ArrayList (list.length); for (T t : list) { arrayList.add(t); } setList(arrayList); } public List getList() { return this.mList; } public void addAll(List list) { if (list == null || list.size() == 0) return; this.mList.addAll(list); } public void addAll(int location, List 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(); } public void swapView(int draggedPos , int currentPos) { //从前往后拖 if(draggedPos < currentPos){ //将被拖拽的节点移动至当前节点 mList.add(currentPos + 1 , mList.get(draggedPos)); //删除拖拽前的节点 mList.remove(draggedPos); } //从后往前拖 else if (draggedPos > currentPos) { //将被拖拽的节点移动至当前节点 mList.add(currentPos , mList.get(draggedPos)); //删除拖拽前的节点 mList.remove(draggedPos + 1); } mHidePosition = currentPos; notifyDataSetChanged(); } }
其次实现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;
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;
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);
//初始化显示被拖动item的image view
dragImageView = new ImageView(getContext());
dragImageView.setTag(DRAG_IMG_NOT_SHOW);
//初始化用于设置dragImageView的参数对象
dragImageViewParams = new WindowManager.LayoutParams();
//获取窗口管理对象,用于后面向窗口中添加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,获取拖动item的bitmap
Bitmap dragBitmap = Bitmap.createBitmap(view.getDrawingCache());
//设置拖动item的参数
dragImageViewParams.gravity = Gravity.TOP | Gravity.LEFT;
//设置拖动item为原item 1.2倍
dragImageViewParams.width = (int)(AMP_FACTOR*dragBitmap.getWidth());
dragImageViewParams.height = (int)(AMP_FACTOR*dragBitmap.getHeight());
//设置触摸点为绘制拖动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;
//设置窗口支持透明度
dragImageViewParams.format = PixelFormat.TRANSLUCENT;
dragImageViewParams.windowAnimations = 0;
//dragImageView为被拖动item的容器,清空上一次的显示
if((int)dragImageView.getTag() == DRAG_IMG_SHOW) {
windowManager.removeView(dragImageView);
dragImageView.setTag(DRAG_IMG_NOT_SHOW);
}
//设置本次被长按的item
dragImageView.setImageBitmap(dragBitmap);
//添加拖动item到屏幕
windowManager.addView(dragImageView, dragImageViewParams);
dragImageView.setTag(DRAG_IMG_SHOW);
isViewonDrag = true;
//设置被长按item不显示
((baseDragableAdapter)getAdapter()).hideView(position);
return true;
}
};
@Override
public boolean onTouchEvent(MotionEvent ev) {
//被按下时记录按下的坐标
if(ev.getAction() == MotionEvent.ACTION_DOWN) {
//获取触摸点相对于屏幕的坐标
downRawX = (int)ev.getRawX();
downRawY = (int)ev.getRawY();
}
//dragImageView处于被拖动时,更新dragImageView位置
else if((ev.getAction() == MotionEvent.ACTION_MOVE) && (isViewonDrag == true)) {
Log.i(LOG_TAG, "" + ev.getRawX() + " " + ev.getRawY());
//设置触摸点为dragImageView中心
dragImageViewParams.x = (int)(ev.getRawX() - dragImageView.getWidth()/2);
dragImageViewParams.y = (int)(ev.getRawY() - dragImageView.getHeight()/2);
//更新窗口显示,移动dragImageView的位置
windowManager.updateViewLayout(dragImageView, dragImageViewParams);
//获取当前触摸点的item position
int currDraggedPosition = pointToPosition((int)ev.getX(), (int)ev.getY());
//如果当前停留位置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);
}
}
实现一个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; public class MyAdapter extends baseDragableAdapter{ 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 list = new ArrayList();
for (int i = 0 ; i < 30 ; i ++) {
list.add("position" + i);
}
adapter.setList(list);
mDragableGv.setAdapter(adapter);
}
}
以上所述是小编给大家介绍的Android实现GridView中的item自由拖动效果,实现一个模拟后台数据登入的效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!



