服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现左滑删除列表功能

Android实现左滑删除列表功能

2022-07-28 11:25peterchen1101 Android

这篇文章主要为大家详细介绍了Android自定义左滑删除列表功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android自定义左滑删除列表的具体代码,供大家参考,具体内容如下

1、布局文件view_left_slide_remove.xml

包含一个RelativeLayout和TextView,RelativeLayout是实际界面,TextView是删除按钮。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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类实现了BaseAdapter。
在getView方法中引用了view_left_slide_remove布局,提供getSubView来导入真正的布局。
OnItemRemoveListener是删除监听器。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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是实际的界面
  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方法里面滑动界面。
VelocityTracker类记录手势。
Scroller类进行滑动操作。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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);
        }
        // 起始位置,当前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);
        }
 
        // 恢复状态
        clear();
 
        // 获取当前界面
        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)) {
          // 开始滑动
          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、测试例子

ContractAdapter继承LeftSlideRemoveAdapter类。
LeftSlideRemoveActivity中使用LeftSlideRemoveListView类。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
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;
  }
 
}

显示如下

Android实现左滑删除列表功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/chennai1101/article/details/68935385

延伸 · 阅读

精彩推荐