Android 可拖拽的GridView效果实现, 长按可拖拽和item实时交换
简单修改,完成自己想要的功能:长按,移到垃圾桶,删除数据。

主要思路是:
1.获取到用户长按的操作
2.获取按下的图片的bitmap以及移动的时候动态刷新镜像
3 action_up的时候判断镜像的位置,进入是否删除逻辑
自定义控件
package com.leafact.GridView; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Handler; import android.os.Vibrator; import android.util.AttributeSet; 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; import android.widget.Toast; /**  * 长按能选中item的,丢入垃圾箱的gridView  *  * @author leafact  *  */ public class MoveGridView extends GridView {   private WindowManager mWindowManager;   /**    * item镜像的布局参数    */   private WindowManager.LayoutParams mWindowLayoutParams;   /**    * 震动器    */   private Vibrator mVibrator;   // 震动的时间,默认为100ms   private long vibratorMs = 100;   // 设置长按时间为1秒   private long responseMS = 1000;   private static boolean isMove = false;   // 按下去的x,y   private int mDownX = 0;   private int mDownY = 0;   // 移动的时候的x,y   private int mMoveX = 0;   private int mMoveY = 0;   // 抬起的x,y   private int mUpX = 0;   private int mUpY = 0;   private int mPoint2ItemTop;   private int mPoint2ItemLeft;   private int mOffset2Top;   private int mOffset2Left;   /**    * 状态栏的高度    */   private int mStatusHeight;   public MoveGridView(Context context, AttributeSet attrs) {     super(context, attrs);     mVibrator = (Vibrator) context         .getSystemService(Context.VIBRATOR_SERVICE);     mWindowManager = (WindowManager) context         .getSystemService(Context.WINDOW_SERVICE);     mStatusHeight = getStatusHeight(context); // 获取状态栏的高度   }   // 要移动的item的位置,默认为INVALID_POSITION=-1   private int mMovePosition = INVALID_POSITION;   /**    * 刚开始拖拽的item对应的View    */   private View mStartMoveItemView = null;   private ImageView mMoveImageView = null;   private Bitmap mMoveBitmap;   private Handler mHandler = new Handler();   // 判断是否能开始移动元素   private Runnable mLongClickRunnable = new Runnable() {     @Override     public void run() {       isMove = true;       mVibrator.vibrate(vibratorMs);       // 根据我们按下的点显示item镜像       createDragImage(mMoveBitmap, mDownX, mDownY);     }   };   @Override   public boolean onTouchEvent(MotionEvent ev) {     switch (ev.getAction()) {     case MotionEvent.ACTION_DOWN:       mDownX = (int) ev.getX();       mDownY = (int) ev.getY();       System.out.println("ACTION_DOWN");       // 根据按下的X,Y坐标获取所点击item的position       mMovePosition = pointToPosition(mDownX, mDownY);       // 如果选中的为非法的位置。则不处理消息       if (mMovePosition == AdapterView.INVALID_POSITION) {         break;       }       mHandler.postDelayed(mLongClickRunnable, responseMS);       mStartMoveItemView = getChildAt(mMovePosition           - getFirstVisiblePosition());       mPoint2ItemTop = mDownY - mStartMoveItemView.getTop();       mPoint2ItemLeft = mDownX - mStartMoveItemView.getLeft();       mOffset2Top = (int) (ev.getRawY() - mDownY);       mOffset2Left = (int) (ev.getRawX() - mDownX);       // 开启mMoveItemView绘图缓存       mStartMoveItemView.setDrawingCacheEnabled(true);       // 获取mMoveItemView在缓存中的Bitmap对象       mMoveBitmap = Bitmap.createBitmap(mStartMoveItemView           .getDrawingCache());       // 这一步很关键,释放绘图缓存,避免出现重复的镜像       mStartMoveItemView.destroyDrawingCache();       break;     case MotionEvent.ACTION_MOVE:       mMoveX = (int) ev.getX();       mMoveY = (int) ev.getY();       // 如果我们在按下的item上面移动,只要不超过item的边界我们就不移除mRunnable       // 依然能监听到longClick       if (!isTouchInItem(mStartMoveItemView, mMoveX, mMoveY)) {         mHandler.removeCallbacks(mLongClickRunnable);       }       // //禁止Gridview侧边进行滑动,移动的时候不许发生侧滑事件       if (isMove) {         onDragItem(mMoveX, mMoveY);         return true;       }       break;     case MotionEvent.ACTION_UP:       mUpX = (int) ev.getX();       mUpY = (int) ev.getY();       mHandler.removeCallbacks(mLongClickRunnable);       if(isMove){         deleteIfNeed();       }       removeDragImage();       isMove = false;       break;     default:       break;     }     return super.onTouchEvent(ev);   }   /**    * 判断是否要删除,满足条件删除    */   private void deleteIfNeed() {     int y = mUpY - mPoint2ItemTop + mOffset2Top         - mStatusHeight;     if(y<50){       if(mUninstallListener!=null)       mUninstallListener.onUninstallListener(mMovePosition);     }   }   /**    * 是否点击在GridView的item上面    *    * @param itemView    * @param x    * @param y    * @return    */   private boolean isTouchInItem(View dragView, int x, int y) {     if (dragView == null) {       return false;     }     int leftOffset = dragView.getLeft();     int topOffset = dragView.getTop();     if (x < leftOffset || x > leftOffset + dragView.getWidth()) {       return false;     }     if (y < topOffset || y > topOffset + dragView.getHeight()) {       return false;     }     return true;   }   /**    * 创建拖动的镜像    *    * @param bitmap    * @param downX    *      按下的点相对父控件的X坐标    * @param downY    *      按下的点相对父控件的X坐标    */   private void createDragImage(Bitmap bitmap, int downX, int downY) {     mWindowLayoutParams = new WindowManager.LayoutParams();     mWindowLayoutParams.format = PixelFormat.TRANSLUCENT; // 图片之外的其他地方透明     mWindowLayoutParams.gravity = Gravity.TOP | Gravity.LEFT;     mWindowLayoutParams.x = downX - mPoint2ItemLeft + mOffset2Left;     mWindowLayoutParams.y = downY - mPoint2ItemTop + mOffset2Top         - mStatusHeight;     mWindowLayoutParams.alpha = 0.55f; // 透明度     mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;     mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;     mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE         | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;     mMoveImageView = new ImageView(getContext());     mMoveImageView.setImageBitmap(bitmap);     mWindowManager.addView(mMoveImageView, mWindowLayoutParams);   }   /**    * 从界面上面移动拖动镜像    */   private void removeDragImage() {     if (mMoveImageView != null) {       mWindowManager.removeView(mMoveImageView);       mMoveImageView = null;     }   }   /**    * 拖动item,在里面实现了item镜像的位置更新,item的相互交换以及GridView的自行滚动    *    * @param x    * @param y    */   private void onDragItem(int moveX, int moveY) {     mWindowLayoutParams.x = moveX - mPoint2ItemLeft + mOffset2Left;     mWindowLayoutParams.y = moveY - mPoint2ItemTop + mOffset2Top         - mStatusHeight;     mWindowManager.updateViewLayout(mMoveImageView, mWindowLayoutParams); // 更新镜像的位置   }   /**    * 获取状态栏的高度    *    * @param context    * @return    */   private static int getStatusHeight(Context context) {     int statusHeight = 0;     Rect localRect = new Rect();     ((Activity) context).getWindow().getDecorView()         .getWindowVisibleDisplayFrame(localRect);     statusHeight = localRect.top;     if (0 == statusHeight) {       Class<?> localClass;       try {         localClass = Class.forName("com.android.internal.R$dimen");         Object localObject = localClass.newInstance();         int i5 = Integer.parseInt(localClass             .getField("status_bar_height").get(localObject)             .toString());         statusHeight = context.getResources().getDimensionPixelSize(i5);       } catch (Exception e) {         e.printStackTrace();       }     }     return statusHeight;   }   /**    * 设置响应拖拽的毫秒数,默认是1000毫秒    *    * @param responseMS    */   public void setResponseMS(long responseMS) {     this.responseMS = responseMS;   }   /**    * 设置震动时间的毫秒数,默认是1000毫秒    *    * @param responseMS    */   public void setVibrator(long vibratorMs) {     this.vibratorMs = vibratorMs;   }   public void setOnUninstallListener(UninstallListener l){     mUninstallListener=l;   };   private UninstallListener mUninstallListener; } MainActivity.java
package com.example.gridviewmovedemo; import java.util.ArrayList; import java.util.HashMap; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.SimpleAdapter; import com.leafact.GridView.MoveGridView; import com.leafact.GridView.UninstallListener; public class MainActivity extends Activity {   private MoveGridView mMoveGridView;   @Override   protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_main);     mMoveGridView = (MoveGridView) findViewById(R.id.gridview);     final ArrayList<HashMap<String, Object>> lstImageItem = new ArrayList<HashMap<String, Object>>();     for (int i = 0; i < 10; i++) {       HashMap<String, Object> map = new HashMap<String, Object>();       map.put("ItemText", "NO." + String.valueOf(i));// 按序号做ItemText       lstImageItem.add(map);     }     final SimpleAdapter saImageItems = new SimpleAdapter(this,         lstImageItem,// 数据来源         R.layout.gridview_item,         // 动态数组与ImageItem对应的子项         new String[] { "ItemText" },         // ImageItem的XML文件里面的一个ImageView,两个TextView ID         new int[] { R.id.ItemText });     // 添加并且显示     mMoveGridView.setAdapter(saImageItems);     //监听到卸载删除数据     mMoveGridView.setOnUninstallListener(new UninstallListener() {       @Override       public void onUninstallListener(int position) {         lstImageItem.remove(position);         saImageItems.notifyDataSetChanged();       }     });   }   @Override   public boolean onCreateOptionsMenu(Menu menu) {     getMenuInflater().inflate(R.menu.main, menu);     return true;   } } UninstallListener.java
package com.leafact.GridView; public interface UninstallListener {   void onUninstallListener(int position); } activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" android:orientation="vertical" tools:context=".MainActivity" > <RelativeLayout android:layout_width="fill_parent" android:layout_height="100dip" android:background="#ccc" > <TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_centerHorizontal="true" android:gravity="center" android:text="卸载" android:textColor="#fff" android:textSize="28sp" /> </RelativeLayout> <com.leafact.GridView.MoveGridView android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:horizontalSpacing="5dip" android:numColumns="3" android:verticalSpacing="5dip" /> </LinearLayout>
gridview_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:background="#2248DD" > <TextView android:id="@+id/ItemText" android:layout_width="wrap_content" android:layout_height="100dip" android:layout_centerHorizontal="true" android:gravity="center" > </TextView> </RelativeLayout>
总结
以上所述是小编给大家介绍的Android实现可拖拽的GridView效果长按可拖拽删除数据源,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对武林网网站的支持!
新闻热点
疑难解答