Android -- RecyclerView实现左滑删除
1,在实际项目中我们常常有对一个列表进行滑删除操作,使用我们昨天的ItemTouchHelper其实也可以实现简单的实现这个功能,先来看一下使用ItemTouchHelper来实现的效果:
2,从上面的效果图我们可以看到,大致的实现了我们的需求,具体操作如下
第一步 :添加表示为START和END标识位
- @Override
- public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
- if (recyclerView.getLayoutManager() instanceof GridLayoutManager) {
- final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN |
- ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT;
- final int swipeFlags = 0;
- return makeMovementFlags(dragFlags, swipeFlags);
- } else {
- final int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
- final int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
- return makeMovementFlags(dragFlags, swipeFlags);
- }
- }
第二步 : 在侧滑过程中删除数据
- @Override
- public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
- int position = viewHolder.getAdapterPosition();
- myAdapter.notifyItemRemoved(position);
- datas.remove(position);
- }
这样就很简单的实现了我们的操作
3,但是上面实现方法有一个短板,就是用户有时候是不小心向左滑动,这样我们最好在滑动后添加一个确定操作的按钮,以确保用户不是手误滑动,这是我们要自定义RecyclerView重写OnTouchEvent方法来实现,先看一下实现的效果:
来说一下整体的思路
第一步:RecyclerView的item布局是由两部分组成,一是我们正常的item,还有一部分是我们还有删除按钮的布局文件,布局文件展示效果如下:
代码如下:
item_linear.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:id="@+id/ll_item"
- >
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- android:layout_marginLeft="5dp"
- android:layout_weight="1"
- android:text="我是标题"
- android:textSize="16dp"/>
- <ImageView
- android:id="@+id/img"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginBottom="5dp"
- android:layout_marginTop="5dp"
- android:src="@mipmap/ic_category_0"
- />
- </LinearLayout>
- <!-- 屏幕右侧外边部分,正常时在屏幕中处于不可见 -->
- <LinearLayout
- android:id="@+id/ll_hidden"
- android:layout_width="50dp"
- android:layout_height="match_parent"
- android:background="#ff0000"
- android:gravity="center"
- >
- <TextView
- android:id="@+id/tv_item_delete"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="删除"
- android:textColor="#ffffff"
- android:textSize="16sp"
- />
- </LinearLayout>
- </LinearLayout>
第二步:创建自定义的RecyclerView,重写onTouchEvent()方法,而重写OnTouchEvent()的大致思路是当用户手指按下时,计算出当前选中的是哪个Item,并获取到该Item对象;然后判断手指移动方向,若左移,则滑动(在滑动之前,先恢复上次的状态);若右移,则恢复;当左移完成之后,“删除”按钮自然就“暴露”在屏幕上可点击的范围了;然后就可以对Item进行删除操作了。 由于代码中的注释很详细了,就不再讲解了
SwipRecyclerView.java
- package com.qianmo.dragrecyclerview;
- import android.content.Context;
- import android.graphics.Rect;
- import android.support.v7.widget.LinearLayoutManager;
- import android.support.v7.widget.RecyclerView;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewConfiguration;
- import android.view.animation.LinearInterpolator;
- import android.widget.LinearLayout;
- import android.widget.Scroller;
- import android.widget.TextView;
- /**
- * Created by Administrator on 2017/3/14 0014.
- * E-Mail:543441727@qq.com
- */
- public class SwipeRecyclerView extends RecyclerView{
- private static final String TAG = "RecycleView";
- private int maxLength, mTouchSlop;
- private int xDown, yDown, xMove, yMove;
- /**
- * 当前选中的item索引(这个很重要)
- */
- private int curSelectPosition;
- private Scroller mScroller;
- private LinearLayout mCurItemLayout, mLastItemLayout;
- private LinearLayout mLlHidden;//隐藏部分
- private TextView mItemContent;
- private LinearLayout mItemDelete;
- /**
- * 隐藏部分长度
- */
- private int mHiddenWidth;
- /**
- * 记录连续移动的长度
- */
- private int mMoveWidth = 0;
- /**
- * 是否是第一次touch
- */
- private boolean isFirst = true;
- private Context mContext;
- /**
- * 删除的监听事件
- */
- private OnRightClickListener mRightListener;
- public void setRightClickListener(OnRightClickListener listener){
- this.mRightListener = listener;
- }
- public SwipeRecyclerView(Context context) {
- this(context, null);
- }
- public SwipeRecyclerView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
- public SwipeRecyclerView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- mContext = context;
- //滑动到最小距离
- mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
- //滑动的最大距离
- maxLength = ((int) (180 * context.getResources().getDisplayMetrics().density + 0.5f));
- //初始化Scroller
- mScroller = new Scroller(context, new LinearInterpolator(context, null));
- }
- @Override
- public boolean onTouchEvent(MotionEvent e) {
- int x = (int)e.getX();
- int y = (int)e.getY();
- switch (e.getAction()){
- case MotionEvent.ACTION_DOWN:
- //记录当前按下的坐标
- xDown = x;
- yDown = y;
- //计算选中哪个Item
- int firstPosition = ((LinearLayoutManager)getLayoutManager()).findFirstVisibleItemPosition();
- Rect itemRect = new Rect();
- final int count = getChildCount();
- for (int i=0; i<count; i++){
- final View child = getChildAt(i);
- if (child.getVisibility() == View.VISIBLE){
- child.getHitRect(itemRect);
- if (itemRect.contains(x, y)){
- curSelectPosition = firstPosition + i;
- break;
- }
- }
- }
- if (isFirst){//第一次时,不用重置上一次的Item
- isFirst = false;
- }else {
- //屏幕再次接收到点击时,恢复上一次Item的状态
- if (mLastItemLayout != null && mMoveWidth > 0) {
- //将Item右移,恢复原位
- scrollRight(mLastItemLayout, (0 - mMoveWidth));
- //清空变量
- mHiddenWidth = 0;
- mMoveWidth = 0;
- }
- }
- //取到当前选中的Item,赋给mCurItemLayout,以便对其进行左移
- View item = getChildAt(curSelectPosition - firstPosition);
- if (item != null) {
- //获取当前选中的Item
- MyAdapter.ViewHolder viewHolder = (MyAdapter.ViewHolder) getChildViewHolder(item);
- mCurItemLayout = viewHolder.ll_item;
- //找到具体元素(这与实际业务相关了~~)
- mLlHidden = (LinearLayout)mCurItemLayout.findViewById(R.id.ll_hidden);
- mItemDelete = (LinearLayout)mCurItemLayout.findViewById(R.id.ll_hidden);
- mItemDelete.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (mRightListener != null){
- //删除
- mRightListener.onRightClick(curSelectPosition, "");
- }
- }
- });
- //这里将删除按钮的宽度设为可以移动的距离
- mHiddenWidth = mLlHidden.getWidth();
- }
- break;
- case MotionEvent.ACTION_MOVE:
- xMove = x;
- yMove = y;
- int dx = xMove - xDown;//为负时:手指向左滑动;为正时:手指向右滑动。这与Android的屏幕坐标定义有关
- int dy = yMove - yDown;//
- //左滑
- if (dx < 0 && Math.abs(dx) > mTouchSlop && Math.abs(dy) < mTouchSlop){
- int newScrollX = Math.abs(dx);
- if (mMoveWidth >= mHiddenWidth){//超过了,不能再移动了
- newScrollX = 0;
- } else if (mMoveWidth + newScrollX > mHiddenWidth){//这次要超了,
- newScrollX = mHiddenWidth - mMoveWidth;
- }
- //左滑,每次滑动手指移动的距离
- scrollLeft(mCurItemLayout, newScrollX);
- //对移动的距离叠加
- mMoveWidth = mMoveWidth + newScrollX;
- }else if (dx > 0){//右滑
- //执行右滑,这里没有做跟随,瞬间恢复
- scrollRight(mCurItemLayout, 0 - mMoveWidth);
- mMoveWidth = 0;
- }
- break;
- case MotionEvent.ACTION_UP://手抬起时
- int scrollX = mCurItemLayout.getScrollX();
- if (mHiddenWidth > mMoveWidth) {
- int toX = (mHiddenWidth - mMoveWidth);
- if (scrollX > mHiddenWidth / 2) {//超过一半长度时松开,则自动滑到左侧
- scrollLeft(mCurItemLayout, toX);
- mMoveWidth = mHiddenWidth;
- } else {//不到一半时松开,则恢复原状
- scrollRight(mCurItemLayout, 0 - mMoveWidth);
- mMoveWidth = 0;
- }
- }
- mLastItemLayout = mCurItemLayout;
- break;
- }
- return super.onTouchEvent(e);
- }
- @Override
- public void computeScroll() {
- if (mScroller.computeScrollOffset()) {
- Log.e(TAG, "computeScroll getCurrX ->" + mScroller.getCurrX());
- mCurItemLayout.scrollBy(mScroller.getCurrX(), 0);
- invalidate();
- }
- }
- /**
- * 向左滑动
- */
- private void scrollLeft(View item, int scorllX){
- Log.e(TAG, " scroll left -> " + scorllX);
- item.scrollBy(scorllX, 0);
- }
- /**
- * 向右滑动
- */
- private void scrollRight(View item, int scorllX){
- Log.e(TAG, " scroll right -> " + scorllX);
- item.scrollBy(scorllX, 0);
- }
- public interface OnRightClickListener{
- void onRightClick(int position, String id);
- }
- }
这样我们就实现了给RecyclerView添加左滑删除了 ,这是GitHub下载链接 See You Next Time !
Android -- RecyclerView实现左滑删除的更多相关文章
- Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(1)
场景: 近期做的TODO APP需要在主页添加一个功能,就是可以左滑删除,右滑完成.看了一下当前其他人做的例如仿探探式的效果,核心功能基本一样,但是和我预想的还是有少量区别,于是干脆自己重头学一遍如何 ...
- Android开发学习之路-PopupWindow和仿QQ左滑删除
这周作业,要做一个类似QQ的左滑删除效果的ListView,因为不想给每个item都放一个按钮,所以决定用PopupWindow,这里记录一下 先放一下效果图: 先说明一下这里面的问题: ①没有做到像 ...
- [转]ANDROID仿IOS微信滑动删除_SWIPELISTVIEW左滑删除例子
转载:http://dwtedx.sinaapp.com/itshare_290.html 本例子实现了滑动删除ListView的Itemdemo的效果.大家都知道.这种创意是来源于IOS的.左滑删除 ...
- Android ListView左滑删除、左滑自定义功能
最近项目需要ListView左滑删除功能,搜集了很多资料发现了一个某一前辈写的库能很简单的实现这个功能,而且有源码,直接拿来使用了. 库名字叫做SwipeMenuListView,下面给大家演示一下使 ...
- 模仿QQ左滑删除
需求: 1.左滑删除 2.向左滑动距离超过一半的时候让它自动滑开,向右滑动超过一半的时候自动隐藏 3.一次只允许滑开一个item 还有,根本不需要自定义view来实现,谨防入坑 布局: <?xm ...
- 类似QQ消息左滑删除的Demo
最近在网上学到一篇类似QQ消息左滑删除的demo,完善了下代码,感觉还不错,特此分享一波: CustomSwipeListView.java 是个继承自ListView的类,里面调用了自定义View ...
- 仿QQ列表左滑删除
一直想写个仿QQ通讯列表左滑删除的效果,今天终于忙里偷闲,简单一个. 大概思路是这样的: 通过 ontouchstartontouchmoveontouchend 结合css3的平移. 不多说,直接上 ...
- tableView左滑删除功能
实现三个代理方法即可 -(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtI ...
- wex5 实战 苹果左滑删除与长按编辑
用了多年苹果,习惯了苹果的左滑删除与长按编辑,特别是短信什么的,很多安卓界面也采用了类似方式. 我的想法突如其来,用wex5也设计一个这样的功能,可以吗? 那句广告词,没有什么不可能. 呵呵. 一 ...
随机推荐
- 在U盘上安装GRUB2直接引导ISO
本文的内容来源于 http://maxmars.net/blog/2012/10/02/boot-multiple-iso-from-usb-using-linux/ 以下所有命令都在 root 用户 ...
- 内置函数time
time import time.time() # 浮点型,给计算机看,随机 时间有三种: First: 时间戳 (time.time()) Second: 结构化时间 可以修改 Third: ...
- 【PyQt5-Qt Designer】QDoubleSpinBox-小数微调框
QDoubleSpinBox-小数微调框 总体说明 大部分的总体说明和QSpinBox的差不多(详见:<PyQt5:微调框1>),这里主要把有差别的地方谈一下(三点). QDoubleSp ...
- word2vec训练好的词向量
虽然早就对NLP有一丢丢接触,但是最近真正对中文文本进行处理才深深感觉到自然语言处理的难度,主要是机器与人还是有很大差异的,毕竟人和人之间都是有差异的,要不然不会讲最难研究的人嘞 ~~~~~~~~~~ ...
- 用A标签实现页面内容定位 点击链接跳到具体位置
经常在维基百科等网站看到目录列表,点击链接会跳到具体的位置,小美眉一直在问是怎么做到的,其实挺简单的,用A标签实现页面内容定位就行了.实例参考微信营销理论手册的目录. 首先用A标签定义目录的链接. & ...
- HDFS介绍及简单操作
目录 1.HDFS是什么? 2.HDFS设计基础与目标 3.HDFS体系结构 3.1 NameNode(NN)3.2 DataNode(DN)3.3 SecondaryNameNode(SNN)3.4 ...
- Auth认证模块
1.auth简介 auth是什么? auth是django内置的用户认证系统,可以快速的实现:登录,注销,修改密码........ 2.autho的使用 1)先创建超级用户 python3 manag ...
- NN中的激活函数【转载】
转自:https://blog.csdn.net/edogawachia/article/details/80043673 1.sigmoid 特点:可以解释,比如将0-1之间的取值解释成一个神经元的 ...
- tf中计算图 执行流程学习【转载】
转自:https://blog.csdn.net/dcrmg/article/details/79028003 https://blog.csdn.net/qian99/article/details ...
- word2vec 评测 window_different
This is a test for word2vecWed Nov 07 16:04:39 2018dir of model1: ./model/window3_ min_count2_worker ...