欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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*拖动效果,实现一个模拟后台数据登入的效果,希望对大家有所帮助