首页 > 系统 > Android > 正文

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

2019-10-24 20:52:40
字体:
来源:转载
供稿:网友
本文实现了GridView的拖拽功能,原理很简单只是在交换位置上记录了X轴的相关坐标,计算了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> 

源码下载

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表