Android实现GridView中的item自由拖动效果

之前的工作中,需要实现一个功能就是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;

/**

* 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(); // 避免脏数据

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();

}

/**

* 交换节点

* @param draggedPos 拖拽的起始节点

* @param currentPos 拖拽的当前节点

*/

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;

/**

* 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);

//初始化显示被拖动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;

/**

* 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实现GridView中的item自由拖动效果,实现一个模拟后台数据登入的效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!

以上是 Android实现GridView中的item自由拖动效果 的全部内容, 来源链接: utcz.com/z/333928.html

回到顶部