前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android实现可拖拽的GridView效果长按可拖拽删除数据源

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

作者头像
砸漏
发布2020-10-29 19:42:44
1.3K0
发布2020-10-29 19:42:44
举报
文章被收录于专栏:恩蓝脚本

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

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

主要思路是:

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

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

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

自定义控件

代码语言:javascript
复制
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

代码语言:javascript
复制
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

代码语言:javascript
复制
package com.leafact.GridView; 
public interface UninstallListener { 
void onUninstallListener(int position); 
} 

activity_main.xml

代码语言:javascript
复制
<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

代码语言:javascript
复制
<?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效果长按可拖拽删除数据源,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对ZaLou.Cn网站的支持!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档