当前位置: 移动技术网 > 移动技术>移动开发>Android > Android实现GridView中的item自由拖动效果

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

2019年07月24日  | 移动技术网移动技术  | 我要评论

之前的工作中,需要实现一个功能就是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自由拖动效果,实现一个模拟后台数据登入的效果,希望对大家有所帮助

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网