温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-04-16 13:48:15 来源:亿速云 阅读:344 作者:小新 栏目:移动开发

小编给大家分享一下Android如何实现可拖拽的GridView效果长按可拖拽删除数据源,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

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效果长按可拖拽删除数据源”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI