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

时间: 2024-12-01 00:57:32

Android实现GridView中的item自由拖动效果的相关文章

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

之前的工作中,需要实现一个功能就是GridView中的item可以自由拖动, 思考了一下,其实实现起来不是很困难,主要工作就是交换节点,以及拖动时的移动效果,下面讲讲具体的实现: 首先声明一个BaseAdapter: package com.dafasoft.dragablegridview; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import a

布局-Android中的GridView中的Item之间空白太大

问题描述 Android中的GridView中的Item之间空白太大 adapter中的getView方法如下 public View getView(int position View convertView ViewGroup parent) { ImageView imageView=new ImageView(context); imageView.setImageBitmap(list.get(position).getBitmap()); imageView.setLayoutPar

Android实现GridView中ImageView动态变换的方法_Android

本文实例讲述了Android实现GridView中ImageView动态变换的方法.分享给大家供大家参考.具体如下: 使用YY影音的时候,发现点击GridView的某一个Item,Item里面的图标会在按下的时候发生变换,变成另外一个图片. 自己写了一个类似的demo,具体步骤如下: 1.创建一个包含Grid的Acitity 2.创建item.xml 里面包含一个imageview和一个textview 3.自定义一个adapter,从baseadapter继承 4.在getView中为每个im

Android实现GridView中ImageView动态变换的方法

本文实例讲述了Android实现GridView中ImageView动态变换的方法.分享给大家供大家参考.具体如下: 使用YY影音的时候,发现点击GridView的某一个Item,Item里面的图标会在按下的时候发生变换,变成另外一个图片. 自己写了一个类似的demo,具体步骤如下: 1.创建一个包含Grid的Acitity 2.创建item.xml 里面包含一个imageview和一个textview 3.自定义一个adapter,从baseadapter继承 4.在getView中为每个im

Android仿支付宝中余额宝的数字动画效果_Android

实现效果图: 下面是具体代码,可直接复制: package com.lcw.rabbit.widget; import android.animation.ObjectAnimator; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; import android.view.animation.AccelerateDecelerateInterpola

Android仿支付宝中余额宝的数字动画效果

实现效果图: 下面是具体代码,可直接复制: package com.lcw.rabbit.widget; import android.animation.ObjectAnimator; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; import android.view.animation.AccelerateDecelerateInterpola

图片选择-Android中gridview中item点击事件及选中标记

问题描述 Android中gridview中item点击事件及选中标记 求大神帮忙,gridview中的item我加载了一个CheckBox我在适配器中设置了CheckBox的点击事件,gridview的item 点击事件就不能得到触发,现在我想实现的是点击某一个item,对这个item进行标记,再次点击就消除标记!就像QQ上的选中图片,然后进行预览和发送一样的效果,求大神解答 解决方案 将布局文件中的checkbox的属性设置一下,android:focusable=""false&

android gridview第一个item

问题描述 android gridview第一个item gridview 中的第一个item中放置了图片和textview,启用线程进行刷新显示textview的内容,其他的item都正常只有第一个item不正常显示,求大神指导 解决方案 你这么问没意义,肯定是你代码有问题,自己打印一些信息,帮助你调试 解决方案二: 怎么不正常显示了,是不是错位了,看看你刷新的图片是不是每次都会不一样大小,把布局弄乱了 解决方案三: Android酱油笔记之Gridview第一个item点击效果问题

btn-Android获取GridView里的item内容时获取的内容不是点击的。

问题描述 Android获取GridView里的item内容时获取的内容不是点击的. 如图,快餐,烧烤这些白色btn是gridview里的item.这个页面生成了多个gridview,我想在点击其中一个btn时候获取btn的text作为参数传递.使用 gridView=new MyGridView(FenleiActivity.this); gridView.setVerticalSpacing(10); gridView.setHorizontalSpacing(15); gridView.s