Android实现GridView中的item*拖动效果
程序员文章站
2024-03-02 21:16:22
之前的工作中,需要实现一个功能就是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*拖动效果
-
Android中RecyclerView布局代替GridView实现类似支付宝的界面
-
Android UI设计系列之自定义SwitchButton开关实现类似IOS中UISwitch的动画效果(2)
-
Android中自定义View实现圆环等待及相关的音量调节效果
-
Android App中ListView仿QQ实现滑动删除效果的要点解析
-
Android实现GridView中的item*拖动效果
-
详解Android Material设计中阴影效果的实现方法
-
Android App中ListView仿QQ实现滑动删除效果的要点解析
-
Android中自定义View实现圆环等待及相关的音量调节效果
-
Android App中实现简单的刮刮卡抽奖效果的实例详解