Android   发布时间:2022-04-28  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Android实现可拖拽的GridView效果长按可拖拽删除数据源大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

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

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

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

主要思路是:@H_944_1@

1.获取用户长按的操作@H_944_1@

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

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

自定义控件@H_944_1@

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); 
      // @L_420_5@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){ 
        @R_618_9421@eIfNeed(); 
      } 
      removeDragImage(); 
      isMove = false; 
      break; 
    default: 
      break; 
    } 
    return super.onTouchEvent(ev); 
  } 
  /** 
   * 判断是否要删除,满足条件删除 
   */ 
  private void @R_618_9421@eIfNeed() { 
    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; 
} 
@H_756_0@mainActivity.java@H_944_1@
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@H_944_1@

package com.leafact.GridView; 
public interface UninstallListener { 
  void onUninstallListener(int position); 
} 

activity_main.xml@H_944_1@

<LinearLayout xmlns:android="http://scheR_397_11845@as.android.com/apk/res/android" 
  xmlns:tools="http://scheR_397_11845@as.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@H_944_1@

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://scheR_397_11845@as.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> 

总结@H_944_1@

以上所述是小编给大家介绍的Android实现可拖拽的GridView效果长按可拖拽删除数据源,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!@H_944_1@

大佬总结

以上是大佬教程为你收集整理的Android实现可拖拽的GridView效果长按可拖拽删除数据源全部内容,希望文章能够帮你解决Android实现可拖拽的GridView效果长按可拖拽删除数据源所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。