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

作者:Leafact 时间:2022-10-22 17:39:32 

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

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

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

主要思路是:

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效果长按可拖拽删除数据源网站的支持!

来源:http://blog.csdn.net/leafact/article/details/49178475

标签:android,gridview,拖拽,删除
0
投稿

猜你喜欢

  • 23种设计模式(12)java模版方法模式

    2021-10-24 11:00:31
  • WPF实现窗体亚克力效果的示例代码

    2022-07-25 10:38:08
  • Flutter 设置全局字体的实现

    2023-05-04 06:27:25
  • Android中实现下载和解压zip文件功能代码分享

    2022-05-31 04:47:26
  • 详解Java异常处理中finally子句的运用

    2023-11-29 10:10:30
  • 详解java动态代理模式

    2023-03-29 13:39:29
  • Unity打开淘宝app并跳转到商品页面功能的实现方法

    2023-06-17 01:05:18
  • Java+swing实现抖音上的表白程序详解

    2023-11-15 21:34:08
  • Java JVM字节码指令集总结整理与介绍

    2021-09-18 17:10:20
  • Java中遍历Map的六种方法实现

    2022-03-21 13:30:58
  • 因Spring AOP导致@Autowired依赖注入失败的解决方法

    2022-10-24 19:44:11
  • c#线程Thread示例

    2022-10-21 00:38:56
  • Android中的深度链接技术实战

    2023-09-20 11:27:18
  • Java线程同步机制_动力节点Java学院整理

    2023-08-01 10:29:47
  • Android studio 混淆配置详解

    2023-02-16 19:17:22
  • Android开发笔记之:Handler Runnable与Thread的区别详解

    2023-11-10 12:29:01
  • Java-JFrame-swing嵌套浏览器的具体步骤

    2022-11-26 19:30:10
  • 基于Fedora14下自带jdk1.6版本 安装jdk1.7不识别的解决方法

    2022-05-17 19:27:39
  • ViewPager实现带引导小圆点与自动跳转的引导界面

    2021-07-11 12:25:18
  • Java之Spring注解开发案例详解

    2022-05-23 05:33:02
  • asp之家 软件编程 m.aspxhome.com