首页 > 系统 > Android > 正文

Android实现可拖拽的GridView效果长按可拖拽删除数据源

2019-10-22 18:20:30
字体:
来源:转载
供稿:网友

Android 可拖拽的GridView效果实现, 长按可拖拽和item实时交换

简单修改,完成自己想要的功能:长按,移到垃圾桶,删除数据。

android,长按拖拽删除,拖拽gridview

主要思路是:

1.获取到用户长按的操作

2.获取按下的图片的bitmap以及移动的时候动态刷新镜像

3 action_up的时候判断镜像的位置,进入是否删除逻辑

自定义控件

package com.leafact.GridView; import android/203187.html">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效果长按可拖拽删除数据源,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对VEVB武林网网站的支持!


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表