溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

怎么在Android中實(shí)現(xiàn)一個(gè)左滑刪除列表功能

發(fā)布時(shí)間:2021-01-19 16:40:35 來(lái)源:億速云 閱讀:154 作者:Leah 欄目:移動(dòng)開發(fā)

怎么在Android中實(shí)現(xiàn)一個(gè)左滑刪除列表功能?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

1、布局文件view_left_slide_remove.xml

包含一個(gè)RelativeLayout和TextView,RelativeLayout是實(shí)際界面,TextView是刪除按鈕。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="40dp">
  <RelativeLayout
    android:id="@+id/view_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
  <TextView
    android:id="@+id/tv_remove"
    android:layout_width="@dimen/left_slide_remove_width"
    android:layout_height="match_parent"
    android:layout_alignParentRight="true"
    android:gravity="center"
    android:text="刪除"
    android:textSize="16sp"
    android:textColor="@color/white"
    android:background="#ffff4b30"
    android:visibility="gone"/>
</RelativeLayout>

2、自定義Adapter

LeftSlideRemoveAdapter類實(shí)現(xiàn)了BaseAdapter。
在getView方法中引用了view_left_slide_remove布局,提供getSubView來(lái)導(dǎo)入真正的布局。
OnItemRemoveListener是刪除監(jiān)聽器。

public static abstract class LeftSlideRemoveAdapter extends BaseAdapter {
 protected Context mContext;
 private OnItemRemoveListener mListener;
 
 public LeftSlideRemoveAdapter(Context context) {
 this.mContext = context;
 }
 
 @Override
 public final View getView(final int position, View convertView, ViewGroup parent) {
 ViewHolder holder;
 if (convertView == null) {
  LayoutInflater inflater = LayoutInflater.from(mContext);
  convertView = inflater.inflate(R.layout.view_left_slide_remove, parent, false);
 
  holder = new ViewHolder();
  holder.viewContent = (RelativeLayout) convertView.findViewById(R.id.view_content);
  holder.tvRmove = (TextView) convertView.findViewById(R.id.tv_remove);
  convertView.setTag(holder);
 
  // viewChild是實(shí)際的界面
  holder.viewChild = getSubView(position, null, parent);
  holder.viewContent.addView(holder.viewChild);
 } else {
  holder = (ViewHolder) convertView.getTag();
  getSubView(position, holder.viewChild, parent);
 }
 holder.tvRmove.setOnClickListener(new View.OnClickListener(){
  @Override
  public void onClick(View v) {
  if (mListener != null) {
   mListener.onItemRemove(position);
   notifyDataSetChanged();
  }
  }
 });
 return convertView;
 }
 
 public abstract View getSubView(int position, View convertView, ViewGroup parent);
}
 
private static class ViewHolder {
 RelativeLayout viewContent;
 View viewChild;
 View tvRmove;
}
 
public static interface OnItemRemoveListener {
 public void onItemRemove(int position);
}

3、自定義左滑刪除列表

在dispatchTouchEvent方法里面捕捉MotionEvent事件。
在onTouchEvent方法里面滑動(dòng)界面。
VelocityTracker類記錄手勢(shì)。
Scroller類進(jìn)行滑動(dòng)操作。

public class LeftSlideRemoveListView extends ListView {
  private final static int SNAP_VELOCITY = 600;
 
  private Scroller mScroller;
  private VelocityTracker mVelocityTracker;
 
  private int mTouchSlop;
  private boolean mIsSlide = false;
  private int mDelta = 0;
  private int mDownX;
  private int mDownY;
  private int mMaxDistence;
  private int mSlidePosition = INVALID_POSITION;
  private OnItemRemoveListener adapterListener;
 
  private OnItemRemoveListener mRemoveListener = new OnItemRemoveListener() {
    @Override
    public void onItemRemove(int position) {
      if (adapterListener != null) {
        adapterListener.onItemRemove(position);
      }
      clear();
      mSlidePosition = INVALID_POSITION;
    }
  };
  private LeftSlideRemoveAdapter mRemoveAdapter;
 
  private View mCurrentContentView, mCurrentRemoveView;
 
  public LeftSlideRemoveListView(Context context) {
    this(context, null);
  }
 
  public LeftSlideRemoveListView(Context context, AttributeSet attrs) {
    super(context, attrs);
 
    mScroller = new Scroller(context);
    mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
 
    mMaxDistence = context.getResources().getDimensionPixelSize(
        R.dimen.left_slide_remove_width);
  }
 
  @Override
  public boolean dispatchTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
      case MotionEvent.ACTION_DOWN:
        addVelocityTracker(ev);
 
        if (!mScroller.isFinished()) {
          return super.dispatchTouchEvent(ev);
        }
        // 起始位置,當(dāng)前position
        mDownX = (int) ev.getX();
        mDownY = (int) ev.getY();
        int position = pointToPosition(mDownX, mDownY);
        if (position == mSlidePosition) break;
 
        mSlidePosition = position;
 
        if (mSlidePosition == INVALID_POSITION ) {
          return super.dispatchTouchEvent(ev);
        }
 
        // 恢復(fù)狀態(tài)
        clear();
 
        // 獲取當(dāng)前界面
        View childView = getChildAt(mSlidePosition - getFirstVisiblePosition());
        mCurrentContentView = childView.findViewById(R.id.view_content);
        mCurrentRemoveView = childView.findViewById(R.id.tv_remove);
 
        break;
      case MotionEvent.ACTION_MOVE:
        if (mCurrentContentView == null) break;
 
        if (Math.abs(getScrollVelocity()) > SNAP_VELOCITY
            || (Math.abs(ev.getX() - mDownX) > mTouchSlop
            && Math.abs(ev.getY() - mDownY) < mTouchSlop)) {
          // 開始滑動(dòng)
          mIsSlide = true;
        }
        break;
      case MotionEvent.ACTION_UP:
        if (mCurrentContentView == null && mIsSlide) break;
 
        // 如果左滑小于4/5,按鈕不顯示
        if (mDelta < mMaxDistence * 4 / 5) {
          mCurrentRemoveView.setVisibility(View.GONE);
          scrollRight();
        } else if (mDelta < mMaxDistence) {
          scrollLeft();
        }
        recycleVelocityTracker();
        mIsSlide = false;
        break;
    }
 
    return super.dispatchTouchEvent(ev);
  }
 
  @Override
  public boolean onTouchEvent(MotionEvent ev) {
    if (mIsSlide && mSlidePosition != INVALID_POSITION) {
      final int action = ev.getAction();
      int x = (int) ev.getX();
      switch (action) {
        case MotionEvent.ACTION_MOVE:
          addVelocityTracker(ev);
 
          int deltaX = mDownX - x;
          mDownX = x;
 
          mDelta += deltaX;
 
          if (mDelta < 0) {
            mCurrentContentView.scrollTo(0, 0);
 
            mDelta = 0;
            mCurrentRemoveView.setVisibility(View.GONE);
          } else if (mDelta >= mMaxDistence) {
            mDelta = mMaxDistence;
            mCurrentContentView.scrollTo(mMaxDistence, 0);
            mCurrentRemoveView.setVisibility(View.VISIBLE);
            mCurrentRemoveView.setTranslationX(0);
          } else {
            mCurrentContentView.scrollBy(deltaX, 0);
            mCurrentRemoveView.setVisibility(View.VISIBLE);
            mCurrentRemoveView.setTranslationX(mMaxDistence - mDelta);
          }
          break;
      }
      return true;
    }
    return super.onTouchEvent(ev);
  }
 
  // 右滑
  private void scrollRight() {
    final int delta = mDelta;
    mScroller.startScroll(delta, 0, -delta, 0, Math.abs(delta));
    mDelta = 0;
    postInvalidate();
  }
 
  // 左滑
  private void scrollLeft() {
    final int delta = mMaxDistence - mDelta;
    mScroller.startScroll(mDelta, 0, delta, 0, Math.abs(delta));
    mDelta = mMaxDistence;
    postInvalidate();
  }
 
  @Override
  public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
      mCurrentContentView.scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
      mCurrentRemoveView.setTranslationX(mMaxDistence - mScroller.getCurrX());
 
      postInvalidate();
 
      if (mScroller.isFinished()) {
        mCurrentContentView.scrollTo(mDelta, 0);
        mCurrentRemoveView.setTranslationX(0);
      }
    }
  }
 
  private void addVelocityTracker(MotionEvent event) {
    if (mVelocityTracker == null) {
      mVelocityTracker = VelocityTracker.obtain();
    }
 
    mVelocityTracker.addMovement(event);
  }
 
  private int getScrollVelocity() {
    mVelocityTracker.computeCurrentVelocity(1000);
    int velocity = (int) mVelocityTracker.getXVelocity();
    return velocity;
  }
 
  private void recycleVelocityTracker() {
    if (mVelocityTracker != null) {
      mVelocityTracker.recycle();
      mVelocityTracker = null;
    }
  }
 
  private void clear() {
    if (mCurrentContentView != null) {
      mDelta = 0;
      mCurrentContentView.scrollTo(0, 0);
      mCurrentContentView = null;
 
      mCurrentRemoveView.setVisibility(View.GONE);
      mCurrentRemoveView = null;
    }
  }
 
  @Override
  public void setAdapter(ListAdapter adapter) {
    if (adapter instanceof LeftSlideRemoveAdapter) {
      super.setAdapter(adapter);
 
      mRemoveAdapter = (LeftSlideRemoveAdapter) adapter;
      mRemoveAdapter.mListener = mRemoveListener;
    } else {
      throw new IllegalArgumentException("Must be LeftSlideRemoveAdapter");
    }
  }
 
  public void setOnItemRemoveListener(OnItemRemoveListener listener) {
    adapterListener = listener;
  }
}

4、測(cè)試?yán)?/strong>

ContractAdapter繼承LeftSlideRemoveAdapter類。
LeftSlideRemoveActivity中使用LeftSlideRemoveListView類。

public class LeftSlideRemoveActivity extends Activity {
  private List<Map<String, String>> mContentList = new ArrayList<Map<String, String>>();
 
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
 
    setContentView(R.layout.activity_left_slide_remove);
 
    Map<String, String> item = new HashMap<String, String>();
    item.put("name", "Peter");
    item.put("address", "ShangHai");
    mContentList.add(item);
 
    item = new HashMap<String, String>();
    item.put("name", "Lily");
    item.put("address", "BeiJing");
    mContentList.add(item);
 
    item = new HashMap<String, String>();
    item.put("name", "Jack");
    item.put("address", "GuangZhou");
    mContentList.add(item);
 
    item = new HashMap<String, String>();
    item.put("name", "Mike");
    item.put("address", "ShengZhen");
    mContentList.add(item);
 
    LeftSlideRemoveListView lv = (LeftSlideRemoveListView) findViewById(R.id.id_listview);
    lv.setAdapter(new ContractAdapter(this));
    lv.setOnItemRemoveListener(new LeftSlideRemoveListView.OnItemRemoveListener() {
      @Override
      public void onItemRemove(int position) {
        mContentList.remove(position);
      }
    });
  }
 
  private class ContractAdapter extends LeftSlideRemoveListView.LeftSlideRemoveAdapter {
 
    public ContractAdapter(Context context) {
      super(context);
    }
 
    @Override
    public int getCount() {
      return mContentList.size();
    }
 
    @Override
    public Object getItem(int position) {
      return position;
    }
 
    @Override
    public long getItemId(int position) {
      return position;
    }
 
    @Override
    public View getSubView(int position, View convertView, ViewGroup parent) {
      ViewHolder holder;
      if (convertView == null) {
        convertView = getLayoutInflater().inflate(
            R.layout.listview_item_customdapter, parent, false);
        holder = new ViewHolder();
        holder.tvName = (TextView) convertView.findViewById(R.id.tv_name);
        holder.tvAddress = (TextView) convertView.findViewById(R.id.tv_address);
 
        convertView.setTag(holder);
      } else {
        holder = (ViewHolder) convertView.getTag();
      }
      Map<String, String> itemData = mContentList.get(position);
      holder.tvName.setText(itemData.get("name"));
      holder.tvAddress.setText(itemData.get("address"));
 
      return convertView;
    }
  }
 
  private class ViewHolder {
    TextView tvName;
    TextView tvAddress;
  }
 
}

關(guān)于怎么在Android中實(shí)現(xiàn)一個(gè)左滑刪除列表功能問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI