RecyclerView进阶-阿里云开发者社区

开发者社区> androidtraveler> 正文

RecyclerView进阶

简介: 上篇文章我们讲解了RecyclerView的基本使用,本篇就让我们承接上篇文章讲下RecyclerView的进阶使用。 没看过上篇的朋友可以点击右边的传送门:《RecyclerView基本使用》 背景 RecyclerView有很多功能待发掘,刚好自己在工作过程中有遇到,因此抱着知识共享和互相学习的态度分享给大家。
+关注继续查看

上篇文章我们讲解了RecyclerView的基本使用,本篇就让我们承接上篇文章讲下RecyclerView的进阶使用

没看过上篇的朋友可以点击右边的传送门:《RecyclerView基本使用》

背景

RecyclerView有很多功能待发掘,刚好自己在工作过程中有遇到,因此抱着知识共享和互相学习的态度分享给大家。

本篇会讲3个RecyclerView的进阶使用。

01.点击监听

大家知道,我们以前使用ListView的时候,ListView有条目点击回调方法setOnItemClickListener。

但是用过RecyclerView的会发现,

竟然没有
竟然没有
竟然没有

是的,真的没有这个方法。

但是如果我真的要实现点击回调,怎么办呢?

这就是这里我们要说的啦。
我们可以通过在Adapter里面提供一个接口来达到类似的效果。

这里的Adapter为ItemClickRecyclerViewAdapter。

1.定义接口

public interface OnItemClickListener {
        void onItemClick(View view, int position);
}

2.定义该接口的变量并提供set方法以便回调回去。

private OnItemClickListener mOnItemClickListener = null;

public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
        this.mOnItemClickListener = mOnItemClickListener;
}

3.在ItemClickRecyclerViewAdapter的onCreateViewHolder()方法里面对view设置点击监听。

@Override
public ItemClickRecyclerViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_main, parent, false);
    view.setOnClickListener(this);
    return new ItemClickRecyclerViewViewHolder(view);
}

NOTE:
为了把点击的位置回调回去,还需要在onBindViewHolder()方法做如下处理:

holder.itemView.setTag(position);

4.让ItemClickRecyclerViewAdapter实现监听并做回调处理。

@Override
public void onClick(View view) {
    if (mOnItemClickListener != null) {
        mOnItemClickListener.onItemClick(view, (int) view.getTag());
    }
}

如此,点击监听就实现了。

02.互换位置

先上图:


好了,让我们看看如何实现上图的效果吧。

1.定义类DragItemTouchHelperCallback继承ItemTouchHelper.Callback

2.定义一个接口用于上下拖动时交换位置。

public interface OnItemCallbackListener {
    /**
     * @param fromPosition 起始位置
     * @param toPosition   移动的位置
     */
    void onMove(int fromPosition, int toPosition);
}

3.DragItemTouchHelperCallback定义OnItemCallbackListener变量并作为参数通过构造函数传递进来。

private OnItemCallbackListener mOnItemCallbackListener;

public DragItemTouchHelperCallback(OnItemCallbackListener mOnItemCallbackListener) {
    this.mOnItemCallbackListener = mOnItemCallbackListener;
}

4.修改getMovementFlags()方法设置为可上下拖拽。

@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
    //设置为可上下拖拽
    int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
    return makeMovementFlags(dragFlags, 0);
}

5.修改onMove()方法提供回调。

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
    /**
     * 回调
     */
    mOnItemCallbackListener.onMove(viewHolder.getAdapterPosition(), target.getAdapterPosition());
    return true;
}

6.让DragVerticalRecyclerViewAdapter实现我们的接口OnItemCallbackListener,并在onMove()方法中执行具体移动操作。

    @Override
    public void onMove(int fromPosition, int toPosition) {
        /**
         * 在这里进行给原数组数据的移动
         * 第一个参数为数据源
         */
        Collections.swap(itemList, fromPosition, toPosition);
        /**
         * 通知数据移动
         */
        notifyItemMoved(fromPosition, toPosition);
    }

7.将DragItemTouchHelperCallback与RecyclerView建立联系。

        private ItemTouchHelper mItemTouchHelper;
        //先实例化Callback
        ItemTouchHelper.Callback callback = new DragItemTouchHelperCallback(mAdapter);
        //用Callback构造ItemtouchHelper
        mItemTouchHelper = new ItemTouchHelper(callback);
        //调用ItemTouchHelper的attachToRecyclerView方法建立联系
        mItemTouchHelper.attachToRecyclerView(mRecyclerView);

到这里,我们的互换位置就完成了。

当然这里默认是长按才可以拖动。
但是用过QQ的会发现直接点击就可以拖动了。


那么如何实现呢?让我们继续探索。
很简单,只需下面几步:

1.重写DragItemTouchHelperCallback中的isLongPressDragEnabled()方法。

    @Override
    public boolean isLongPressDragEnabled() {
        return false;
    }

2.在DragVerticalRecyclerViewActivity提供ItemTouchHelper的get()方法。

    public ItemTouchHelper getItemTouchHelper() {
        return mItemTouchHelper;
    }

3.在onBindViewHolder()方法中设置触摸监听,然后调用startDrag()方法进行移动。

        holder.itemView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                ItemTouchHelper itemTouchHelper = ((DragVerticalRecyclerViewActivity) (activity)).getItemTouchHelper();
                if (itemTouchHelper != null) {
                    itemTouchHelper.startDrag(holder);
                }
                return true;
            }
        });

如此便实现了。

03.滑动删除

先上图



这里我们简单实现左滑右滑处理。

我们在原先的基础上做处理。
不过为了避免事件冲突,我们把点击上下拖拽改为长按上下拖拽。

然后说下左右滑动的处理:
1.在DragItemTouchHelperCallback的getMovementFlags()方法增加左右滑动。

    @Override
    public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        //设置为可上下拖拽
        int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN;
        //设置侧滑方向为左右
        int swipeFlags = ItemTouchHelper.START | ItemTouchHelper.END;
        return makeMovementFlags(dragFlags, swipeFlags);
    }

2.OnItemCallbackListener接口增加左滑右滑回调。

public interface OnItemCallbackListener {
    /**
     * @param fromPosition 起始位置
     * @param toPosition   移动的位置
     */
    void onMove(int fromPosition, int toPosition);

    //右滑
    void onSwipeRight(int position);

    //左滑
    void onSwipeLift(int position);
}

3.在DragItemTouchHelperCallback的onSwiped()方法中调用。

    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
        if (direction == ItemTouchHelper.END) {
            //Item滑动方向为右
            mOnItemCallbackListener.onSwipeRight(viewHolder.getAdapterPosition());
        } else if (direction == ItemTouchHelper.START) {
            //Item滑动方向为左
            mOnItemCallbackListener.onSwipeLift(viewHolder.getAdapterPosition());
        }
    }

4.在DragVerticalRecyclerViewAdapter实现左滑右滑接口方法。

    @Override
    public void onSwipeRight(int position) {
        itemList.remove(position);
        notifyItemRemoved(position);
        Toast.makeText(activity, "swipe right", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onSwipeLift(int position) {
        itemList.remove(position);
        notifyItemRemoved(position);
        Toast.makeText(activity, "swipe left", Toast.LENGTH_SHORT).show();
    }

这里简单做了移除item操作。如果要做一些其他的操作,就在这里的回调进行处理。

其中notifyItemRemoved(position);必写。

这样左滑右滑就实现了。是不是很简单。

代码点击源代码

昵称: 安卓小哥
邮箱: nesger.zhan@gmail.com
博客: https://nesger.github.io/
GitHub: https://github.com/nesger

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26729 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9480 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
11189 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
9048 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13163 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
4008 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6884 0
+关注
androidtraveler
一名 Android 开发工程师。 乐于分享,乐于探讨,共同学习。 个人公众号:AndroidTraveler
15
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载