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

自定义GridView并且实现拖拽(附源码)

程序员文章站 2023-10-19 14:32:59
写在前面的话 本篇blog实现了gridview的拖拽功能。方法和上一篇自定义listview实现拖拽listitem项交换位置一个原理。只是在交换位置上记录了x轴的相关坐...
写在前面的话
本篇blog实现了gridview的拖拽功能。方法和上一篇自定义listview实现拖拽listitem项交换位置一个原理。只是在交换位置上记录了x轴的相关坐标,计算了x轴的相关变量。

实现效果图如下
自定义GridView并且实现拖拽(附源码) 
说明:
本篇给出实现代码,但是不做任何说明。如需了解请看上一篇blog:自定义listview实现拖拽listitem项交换位置

文件代码:
1、mainactivity.java
复制代码 代码如下:

package com.jay.draggridview;
import java.lang.reflect.field;
import java.util.arraylist;
import java.util.list;
import android.os.bundle;
import android.app.activity;
import android.content.context;
import android.util.log;
import android.view.layoutinflater;
import android.view.menu;
import android.view.view;
import android.view.viewgroup;
import android.widget.arrayadapter;
import android.widget.imageview;
public class mainactivity extends activity {

private static list<string> list = null;
//自定义适配器
private draggridadapter adapter = null;

@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
//初始化数据
initdata();

//后面用到的自定义gridview
draggridview draggridview = (draggridview)findviewbyid(r.id.drag_grid);
adapter = new draggridadapter(this, list);
draggridview.setadapter(adapter);
}


public void initdata(){
list = new arraylist<string>();
for(int i= 0 ; i < 12 ; i++){
list.add("grid_"+i%12);
}
}



public static class draggridadapter extends arrayadapter<string>{

public draggridadapter(context context, list<string> objects) {
super(context, 0, objects);
}
public list<string> getlist(){
return list;
}
@override
public view getview(int position, view convertview, viewgroup parent) {
view view = convertview;
if(view==null){
view = layoutinflater.from(getcontext()).inflate(r.layout.drag_grid_item, null);
}
try {
log.v("item", "------"+getitem(position));
//根据文件名获取资源文件夹中的图片资源
field f= (field)r.drawable.class.getdeclaredfield(getitem(position));
int i=f.getint(r.drawable.class);
imageview imageview= (imageview)view.findviewbyid(r.id.drag_grid_item_image);
imageview.setimageresource(i);
} catch (securityexception e) {
e.printstacktrace();
} catch (nosuchfieldexception e) {
e.printstacktrace();
} catch (illegalargumentexception e) {
e.printstacktrace();
} catch (illegalaccessexception e) {
e.printstacktrace();
}
return view;
}
}
}

2、draggridview.java
复制代码 代码如下:

package com.jay.draggridview;
import com.jay.draggridview.mainactivity.draggridadapter;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.pixelformat;
import android.util.attributeset;
import android.view.gravity;
import android.view.motionevent;
import android.view.view;
import android.view.viewgroup;
import android.view.windowmanager;
import android.widget.adapterview;
import android.widget.gridview;
import android.widget.imageview;
import android.widget.toast;
public class draggridview extends gridview{
//定义基本的成员变量
private imageview dragimageview;
private int dragsrcposition;
private int dragposition;
//x,y坐标的计算
private int dragpointx;
private int dragpointy;
private int dragoffsetx;
private int dragoffsety;
private windowmanager windowmanager;
private windowmanager.layoutparams windowparams;
private int scaledtouchslop;
private int upscrollbounce;
private int downscrollbounce;


public draggridview(context context, attributeset attrs) {
super(context, attrs);
}


@override
public boolean onintercepttouchevent(motionevent ev) {
if(ev.getaction()==motionevent.action_down){
int x = (int)ev.getx();
int y = (int)ev.gety();

dragsrcposition = dragposition = pointtoposition(x, y);
if(dragposition==adapterview.invalid_position){
return super.onintercepttouchevent(ev);
}

viewgroup itemview = (viewgroup) getchildat(dragposition-getfirstvisibleposition());
dragpointx = x - itemview.getleft();
dragpointy = y - itemview.gettop();
dragoffsetx = (int) (ev.getrawx() - x);
dragoffsety = (int) (ev.getrawy() - y);

view dragger = itemview.findviewbyid(r.id.drag_grid_item_drag);
//如果选中拖动图标
if(dragger!=null&&dragpointx>dragger.getleft()&&dragpointx<dragger.getright()&&dragpointy>dragger.gettop()&&dragpointy<dragger.getbottom()+20){

upscrollbounce = math.min(y-scaledtouchslop, getheight()/4);
downscrollbounce = math.max(y+scaledtouchslop, getheight()*3/4);

itemview.setdrawingcacheenabled(true);
bitmap bm = bitmap.createbitmap(itemview.getdrawingcache());
startdrag(bm, x, y);
}
return false;
}
return super.onintercepttouchevent(ev);
}



@override
public boolean ontouchevent(motionevent ev) {
if(dragimageview!=null&&dragposition!=invalid_position){
int action = ev.getaction();
switch(action){
case motionevent.action_up:
int upx = (int)ev.getx();
int upy = (int)ev.gety();
stopdrag();
ondrop(upx,upy);
break;
case motionevent.action_move:
int movex = (int)ev.getx();
int movey = (int)ev.gety();
ondrag(movex,movey);
break;
default:break;
}
return true;
}
return super.ontouchevent(ev);
}



public void startdrag(bitmap bm, int x, int y){
stopdrag();

windowparams = new windowmanager.layoutparams();
windowparams.gravity = gravity.top|gravity.left;
windowparams.x = x - dragpointx + dragoffsetx;
windowparams.y = y - dragpointy + dragoffsety;
windowparams.width = windowmanager.layoutparams.wrap_content;
windowparams.height = windowmanager.layoutparams.wrap_content;
windowparams.flags = windowmanager.layoutparams.flag_not_focusable
| windowmanager.layoutparams.flag_not_touchable
| windowmanager.layoutparams.flag_keep_screen_on
| windowmanager.layoutparams.flag_layout_in_screen;
windowparams.format = pixelformat.translucent;
windowparams.windowanimations = 0;

imageview imageview = new imageview(getcontext());
imageview.setimagebitmap(bm);
windowmanager = (windowmanager)getcontext().getsystemservice("window");
windowmanager.addview(imageview, windowparams);
dragimageview = imageview;
}

public void ondrag(int x, int y){
if(dragimageview!=null){
windowparams.alpha = 0.8f;
windowparams.x = x - dragpointx + dragoffsetx;
windowparams.y = y - dragpointy + dragoffsety;
windowmanager.updateviewlayout(dragimageview, windowparams);
}

int tempposition = pointtoposition(x, y);
if(tempposition!=invalid_position){
dragposition = tempposition;
}

//滚动
if(y<upscrollbounce||y>downscrollbounce){
//使用setselection来实现滚动
setselection(dragposition);
}
}

public void ondrop(int x, int y){
//为了避免滑动到分割线的时候,返回-1的问题
int tempposition = pointtoposition(x, y);
if(tempposition!=invalid_position){
dragposition = tempposition;
}
//超出边界处理
if(y<getchildat(0).gettop()){
//超出上边界
dragposition = 0;
}else if(y>getchildat(getchildcount()-1).getbottom()||(y>getchildat(getchildcount()-1).gettop()&&x>getchildat(getchildcount()-1).getright())){
//超出下边界
dragposition = getadapter().getcount()-1;
}
//数据交换
if(dragposition!=dragsrcposition&&dragposition>-1&&dragposition<getadapter().getcount()){
draggridadapter adapter = (draggridadapter)getadapter();
string dragitem = adapter.getitem(dragsrcposition);
adapter.remove(dragitem);
adapter.insert(dragitem, dragposition);
toast.maketext(getcontext(), adapter.getlist().tostring(), toast.length_short).show();
}
}


/***
* 停止拖动,去掉拖动时候的影像
*/
public void stopdrag(){
if(dragimageview != null){
windowmanager.removeview(dragimageview);
dragimageview = null;
}
}
}

3、activity_main.xml
复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff"
android:padding="10dip"
>
<com.jay.draggridview.draggridview
android:id="@+id/drag_grid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:cachecolorhint="#00000000"
android:numcolumns="3"
android:stretchmode="columnwidth"
android:verticalspacing="5dip"
android:horizontalspacing="20dip"
android:background="#ffffff"/>
</linearlayout>

4、drag_grid_item.xml
复制代码 代码如下:

<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingleft="5dip"
android:paddingright="5dip">
<imageview android:id="@+id/drag_grid_item_image"
android:layout_margin="5dip"
android:layout_alignparenttop="true"
android:layout_width="fill_parent"
android:layout_height="60dip"/>
<imageview android:id="@+id/drag_grid_item_drag"
android:src="@drawable/p32_24_1"
android:layout_alignparenttop="true"
android:layout_alignparentright="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</relativelayout>

源码下载