前三篇文章

android v7兼容包RecyclerView的使用(三)——布局管理器的使用

android v7兼容包RecyclerView的使用(二)

android v7兼容包RecyclerView的使用(一)

介绍了RecyclerView的使用以及常见的相关类和布局管理器的灵活之处。写了这么多篇,还没涉及到用户交互,那么怎么处理点击事件呢。

在RecyclerView中你会惊奇的发现,该类中并没有OnItemClickListener监听器监听我们的单击事件,也没有OnItemLongClickListener监听器监听我们的长按事件。取而代之的是OnItemTouchListener监听器,那么该怎样实现我们的点击事件和长按事件呢。

我们的代码是基于上篇文章布局管理器的代码,在其基础上加入事件监听。

假设让我们自己来事件点击事件,我们比方会使用ViewHolder来间接处理事件。首先在适配器中添加监听器接口。

  1. interface OnItemClickListener {
  2. void onClick(View v);
  3. }
  4. interface OnItemLongClickListener {
  5. void onLongClick(View v);
  6. }
  7. private OnItemClickListener onClickListener;
  8. private OnItemLongClickListener onLongClickListener;

然后重载构造函数,使其能够接收监听器实例

  1. public CardViewAdapter(String[] data) {
  2. this(data, null, null);
  3. }
  4. public CardViewAdapter(String[] data, OnItemClickListener onClickListener) {
  5. this(data, onClickListener, null);
  6. }
  7. public CardViewAdapter(String[] data, OnItemClickListener onClickListener,
  8. OnItemLongClickListener onLongClickListener) {
  9. this.data = data;
  10. this.onClickListener = onClickListener;
  11. this.onLongClickListener = onLongClickListener;
  12. }

终于会调用三參数的构造器,在该构造器内完毕赋值。

将原来的ViewHolder构造函数进行改造,使其处理点击事件,当然也能够直接在onCreateViewHolder函数里处理点击事件。

  1. public ViewHolder(View itemLayoutView,
  2. final OnItemClickListener onClickListener,
  3. final OnItemLongClickListener onLongClickListener) {
  4. super(itemLayoutView);
  5. info = (TextView) itemLayoutView.findViewById(R.id.info_text);
  6. itemLayoutView.setOnClickListener(new OnClickListener() {
  7. @Override
  8. public void onClick(View v) {
  9. //在监听器不为空的时候,进行回调
  10. if (onClickListener != null) {
  11. onClickListener.onClick(v);
  12. }
  13. }
  14. });
  15. itemLayoutView.setOnLongClickListener(new OnLongClickListener() {
  16. @Override
  17. public boolean onLongClick(View v) {
  18. //在监听器不为空的时候,进行回调
  19. if (onLongClickListener != null) {
  20. onLongClickListener.onLongClick(v);
  21. }
  22. //返回true,消费掉该事件,阻止其继续传递
  23. return true;
  24. }
  25. });
  26. }

细致一看,事实上代码还是挺多的,那么让我们调用一下。

  1. mAdapter = new CardViewAdapter(data,new OnItemClickListener() {
  2. @Override
  3. public void onClick(View v) {
  4. TextView info = (TextView) v.findViewById(R.id.info_text);
  5. Toast.makeText(getApplicationContext(), "单击"+info.getText(), Toast.LENGTH_LONG).show();
  6. }
  7. },new OnItemLongClickListener() {
  8. @Override
  9. public void onLongClick(View v) {
  10. TextView info = (TextView) v.findViewById(R.id.info_text);
  11. Toast.makeText(getApplicationContext(), "长按"+info.getText(), Toast.LENGTH_LONG).show();
  12. }
  13. });

后面两个參数能够传空值,代表不设置监听器。

执行效果图例如以下。



我们会发现,上面的代码耦合性还是有点高,事件直接与适配器发生了耦合,除此之外,我们还应该有更好的方法来处理这个点击事件。是的,不是有OnItemTouchListener监听器吗,再配合手势不就能够吗。

好了,看代码吧,详解在凝视中。

  1. package cn.edu.zafu.layoutmanager;
  2. import android.content.Context;
  3. import android.support.v7.widget.RecyclerView;
  4. import android.view.GestureDetector;
  5. import android.view.MotionEvent;
  6. import android.view.View;
  7. /**
  8. * 监听器,实现OnItemTouchListener接口
  9. *
  10. * @author lizhangqu
  11. *
  12. * 2015-3-12
  13. */
  14. public class RecyclerItemClickListener implements
  15. RecyclerView.OnItemTouchListener {
  16. private OnItemClickListener mListener;
  17. private GestureDetector mGestureDetector;
  18. // 点击回调
  19. public interface OnItemClickListener {
  20. public void onItemClick(View view, int position);
  21. public void onItemLongClick(View view, int position);
  22. }
  23. public RecyclerItemClickListener(Context context,
  24. final RecyclerView recyclerView, OnItemClickListener listener) {
  25. mListener = listener;
  26. // 识别并处理手势
  27. mGestureDetector = new GestureDetector(context,
  28. new GestureDetector.SimpleOnGestureListener() {
  29. @Override
  30. public boolean onSingleTapUp(MotionEvent e) {
  31. // 轻击触摸屏后,弹起,必须返回true,否则无法触发单击
  32. return true;
  33. }
  34. @Override
  35. public void onLongPress(MotionEvent e) {
  36. // 长按
  37. // 依据findChildViewUnder(float x, float y)来算出哪个item被选择了
  38. View childView = recyclerView.findChildViewUnder(
  39. e.getX(), e.getY());
  40. // 有item被选则且监听器不为空触发长按事件
  41. if (childView != null && mListener != null) {
  42. mListener.onItemLongClick(childView,
  43. recyclerView.getChildPosition(childView));
  44. }
  45. }
  46. });
  47. }
  48. @Override
  49. public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
  50. View childView = view.findChildViewUnder(e.getX(), e.getY());
  51. if (childView != null && mListener != null
  52. && mGestureDetector.onTouchEvent(e)) {
  53. // 触发单击事件
  54. mListener.onItemClick(childView, view.getChildPosition(childView));
  55. return true;
  56. }
  57. return false;
  58. }
  59. @Override
  60. public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
  61. }
  62. }

在activity中调用

  1. mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(getApplicationContext(), mRecyclerView, new OnItemClickListener() {
  2. @Override
  3. public void onItemLongClick(View view, int position) {
  4. Toast.makeText(getApplicationContext(), "长按"+data[position], Toast.LENGTH_SHORT).show();
  5. }
  6. @Override
  7. public void onItemClick(View view, int position) {
  8. Toast.makeText(getApplicationContext(), "短按"+data[position], Toast.LENGTH_SHORT).show();
  9. }
  10. }));

非常明显,另外一种方式与适配器进行了解耦。应该说优于第一种方法。

那么还有没有方法处理点击事件呢。让我们从万能的github上搜索一下。

https://github.com/lucasr/twoway-view

在该项目的sample文件夹下有个类里面有这样一段代码

  1. final ItemClickSupport itemClick = ItemClickSupport.addTo(mRecyclerView);
  2. itemClick.setOnItemClickListener(new OnItemClickListener() {
  3. @Override
  4. public void onItemClick(RecyclerView parent, View child, int position, long id) {
  5. mToast.setText("Item clicked: " + position);
  6. mToast.show();
  7. }
  8. });
  9. itemClick.setOnItemLongClickListener(new OnItemLongClickListener() {
  10. @Override
  11. public boolean onItemLongClick(RecyclerView parent, View child, int position, long id) {
  12. mToast.setText("Item long pressed: " + position);
  13. mToast.show();
  14. return true;
  15. }
  16. });

上述代码有个ItemClickSupport 类,对的,该类就是提供事件的支持。那么该类在哪里呢,事实上它在该项目的core文件夹下。我直接将其该文件夹下的代码拷至我的项目的包中,删除一个不相关的类,就直接使用了,当然还须要拷一个资源文件就是ids.xml

实际执行效果呢,是跟上面两种方式是一样的,那么它的实现由什么差别呢,事实上与另外一种方式没什么大的差别,基本上就是OnItemTouchListener 加手势实现的,仅仅只是其逻辑可能更加严谨,设计更加优秀罢了。除此之外,该文件夹下另一个ItemSelectionSupport类,该类提供了item选择的功能,提供了单选多选方式,然而呢,在我測试时发现存在bug,所以呢,这个类的使用就跳过了。

至此,RecyclerView的点击事件就处理完了。

源代码下载

http://download.csdn.net/detail/sbsujjbcy/8495337

android v7兼容包RecyclerView的使用(四)——点击事件的不同方式处理的更多相关文章

  1. android v4兼容包

    一句话解释android兼容包就是:支持更多的组件,样式更好看了.好粗糙的解释啊! 我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library ...

  2. 转:android Support 兼容包详解

    本文转自stormzhang的ANDROID SUPPORT兼容包详解 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清 ...

  3. android中RecyclerView控件实现点击事件

    RecyclerView控件实现点击事件跟ListView控件不同,并没有提供类似setOnItemClickListener()这样的注册监听器方法,而是需要自己给子项具体的注册点击事件. 本文的例 ...

  4. 为RecyclerView添加item的点击事件

    RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一下观察者模式. ...

  5. android学习之4种点击事件的响应方式

    如题,下面就一一列出对点击事件响应的4种方式: 第一种:内部类的形式: package com.example.dail; import android.net.Uri; import android ...

  6. Android中点击事件的实现方式

    在之前博文中多次使用了点击事件的处理实现,有朋友就问了,发现了很多按钮的点击实现,但有很多博文中使用的实现方式有都不一样,到底是怎么回事.今天我们就汇总一下点击事件的实现方式. 点击事件的实现大致分为 ...

  7. 33、Android Support兼容包详解(转载)

    原文转自:微信分享 2015-03-31 22:11 背景 来自于知乎上邀请回答的一个问题Android中AppCompat和Holo的一个问题?, 看来很多人还是对这些兼容包搞不清楚,那么干脆写篇博 ...

  8. Android MultiDex兼容包怎么使用?

    在Android系统中安装应用的时候,需要对Dex进行优化,但由于其处理工具DexOpt的限制,导致其id的数目不能够超过65536个.而MultiDex兼容包的出现,就很好的解决了这个问题,它可以配 ...

  9. Android Emoji兼容包使用详解

    Emoji兼容性 我们经常会遇到这样的问题: 给朋友发的emoji表情, 在自己手机上展示是正常的, 但是到朋友手机上, 却没有展示出来, 或者展示出来了, 但是也跟自己手机上展示的不一样. 所以,  ...

随机推荐

  1. php 双向队列类

    (deque,全名double-ended queue)是一种具有队列和栈的性质的数据结构.双向队列中的元素能够从两端弹出,其限定插入和删除操作在表的两端进行. 在实际使用中,还能够有输出受限的双向队 ...

  2. zoj3795 Grouping --- 良好的沟通,寻找最长的公路

    给定一个图,为了保持图分裂至少成多个集合的集合内可以使点没有直接或间接的关系. 首先,题意可以得到图中可能含有环.该环的内侧是肯定是要被拆卸. 图点降低建DAG画画,能想象..图从零点渗透深入,在点中 ...

  3. Android采用Application总结一下

    什么是 Application Application和Activity,Service由于是android框架的一个系统组件,当android程序启动时系统会创建一个 application对象.用 ...

  4. 深入理解Tomcat系列之二:源码调试环境搭建(转)

    前言 最近对Tomcat的源码比较感兴趣,于是折腾了一番.要调试源码首先需要搭建环境,由于参考了几篇帖子发现都不怎么靠谱,最后还是折腾出来了,然而却花了足足一天的时间去搭建这个环境.发现都不是帖子的问 ...

  5. poj3280(区间dp)

    题目连接:http://poj.org/problem?id=3280 题意:给定一个长度为m(m<=2000)的小写字母字符串,在给定组成该字符串的n(n<=26)个字符的添加和删除费用 ...

  6. Beijing Perl Workshop - Augest 10th, 2013

    Beijing Perl Workshop - Augest 10th, 2013 Beijing Perl Workshop

  7. 【剑指offer】旋转数组的最小值

    採用二分查找的策略,重点要考虑一些边界情况:旋转了0元素.即输入的是一个升序排列的数组.仅仅包括一个数字的数组.有非常多反复数字的数组等. AC代码: #include<stdio.h> ...

  8. RabbitMq消息序列化简述

    涉及网络传输的应用.序列化不可避免. 发送端以某种规则将消息转成byte数组进行发送. 接收端则以约定的规则进行byte[]数组的解析. 序列化的选择能够是jdk序列化,hessian,jackson ...

  9. redhat linux 5上创建本地yum源

    1.挂载光驱 [root@rh5rac1 ~]#mkdir -p /mnt/cdrom [root@rh5rac1 ~]#mount /dev/cdrom /mnt/cdrom 2.将redhat光盘 ...

  10. HttpClient 网络优化

    HttpClient 网络优化 尽管Android官网推荐在2.3及后续版本中使用HttpURLConnection作为网络开发首选类,但在连接管理和线程安全方面,HttpClient还是具有很大优势 ...