为RecyclerView添加item的点击事件
RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一下观察者模式。
其实在 这篇文章 中已经提到如何实现,但是里面有很多不规范的地方,而且没有完整的代码。
最终目的
模拟ListView的setOnItemClickListener()方法,调用者只须调用类似于setOnItemClickListener的东西就能获得被点击item的相关数据。
原理
为RecyclerView的每个子item设置setOnClickListener,然后在onClick中再调用一次对外封装的接口,将这个事件传递给外面的调用者。而“为RecyclerView的每个子item设置setOnClickListener”在Adapter中设置。其实直接在onClick中也能完全处理item的点击事件,但是这样会破坏代码的逻辑。
步骤
adapter中
自定义一个继承自RecyclerView.Adapter的MyAdapter。
1.在MyAdapter中定义如下接口,模拟ListView的OnItemClickListener:
//define interface
public static interface OnItemClickListener {
void onItemClick(View view , int position);
}
声明一个这个接口的变量
private OnItemClickListener mOnItemClickListener = null;
在onCreateViewHolder()中为每个item添加点击事件
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
ViewHolder vh = new ViewHolder(view);
//将创建的View注册点击事件
view.setOnClickListener(this);
return vh;
}
将点击事件转移给外面的调用者:
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//注意这里使用getTag方法获取position
mOnItemClickListener.onItemClick(v,(int)v.getTag());
}
}
注意上面调用接口的onItemClick()中的v.getTag()方法,这需要在onBindViewHolder()方法中设置和item的position
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将position保存在itemView的Tag中,以便点击时进行获取
viewHolder.itemView.setTag(position);
}
最后暴露给外面的调用者,定义一个设置Listener的方法():
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
以上所有步骤都发生在自定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。
在Activity中使用
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//创建默认的线性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
//创建并设置Adapter
mAdapter = new MyAdapter(data);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(View view , int position){
Toast.makeText(MainActivity.this, data[position], ).show();
}
});
完整代码
MyAdapter.java
package com.example.recyclerviewdemo; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
private String[] datas;
public MyAdapter(String[] datas) {
this.datas = datas;
}
private OnItemClickListener mOnItemClickListener = null; //define interface
public static interface OnItemClickListener {
void onItemClick(View view , int position);
} @Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
ViewHolder vh = new ViewHolder(view);
//将创建的View注册点击事件
view.setOnClickListener(this);
return vh;
} @Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将position保存在itemView的Tag中,以便点击时进行获取
viewHolder.itemView.setTag(position);
} @Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//注意这里使用getTag方法获取position
mOnItemClickListener.onItemClick(v,(int)v.getTag());
}
} public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
} //获取数据的数量
@Override
public int getItemCount() {
return datas.length;
}
//自定义的ViewHolder,持有每个Item的的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View view){
super(view);
mTextView = (TextView) view.findViewById(R.id.text);
}
}
}
item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="50dip"
>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
MainActivity.java
package com.example.recyclerviewdemo; import com.example.recyclerviewdemo.MyAdapter.OnItemClickListener; import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast; public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private MyAdapter mAdapter;
private String[] data= new String[] {"aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb","aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb" }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//创建默认的线性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
//创建并设置Adapter
mAdapter = new MyAdapter(data);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(View view , int position){
Toast.makeText(MainActivity.this, data[position], ).show();
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</RelativeLayout>
总结
在ListView中我们是调用ListView的setOnItemClickListener:
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
...
}
});
而在我们这里是调用mAdapter的setOnItemClickListener。
RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一下观察者模式。
其实在 这篇文章 中已经提到如何实现,但是里面有很多不规范的地方,而且没有完整的代码。
最终目的
模拟ListView的setOnItemClickListener()方法,调用者只须调用类似于setOnItemClickListener的东西就能获得被点击item的相关数据。
原理
为RecyclerView的每个子item设置setOnClickListener,然后在onClick中再调用一次对外封装的接口,将这个事件传递给外面的调用者。而“为RecyclerView的每个子item设置setOnClickListener”在Adapter中设置。其实直接在onClick中也能完全处理item的点击事件,但是这样会破坏代码的逻辑。
步骤
adapter中
自定义一个继承自RecyclerView.Adapter的MyAdapter。
1.在MyAdapter中定义如下接口,模拟ListView的OnItemClickListener:
//define interface
public static interface OnItemClickListener {
void onItemClick(View view , int position);
}
声明一个这个接口的变量
private OnItemClickListener mOnItemClickListener = null;
在onCreateViewHolder()中为每个item添加点击事件
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
ViewHolder vh = new ViewHolder(view);
//将创建的View注册点击事件
view.setOnClickListener(this);
return vh;
}
将点击事件转移给外面的调用者:
@Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//注意这里使用getTag方法获取position
mOnItemClickListener.onItemClick(v,(int)v.getTag());
}
}
注意上面调用接口的onItemClick()中的v.getTag()方法,这需要在onBindViewHolder()方法中设置和item的position
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将position保存在itemView的Tag中,以便点击时进行获取
viewHolder.itemView.setTag(position);
}
最后暴露给外面的调用者,定义一个设置Listener的方法():
public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
}
以上所有步骤都发生在自定义的adapter中,典型的观察者模式,有点绕的地方在于,这里涉及到两个观察者模式的使用,view的setOnClickListener本来就是观察者模式,我们将这个观察者模式的事件监听传递给了我们自己的观察者模式。
在Activity中使用
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//创建默认的线性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
//创建并设置Adapter
mAdapter = new MyAdapter(data);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(View view , int position){
Toast.makeText(MainActivity.this, data[position], ).show();
}
});
完整代码
MyAdapter.java
package com.example.recyclerviewdemo; import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView; public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> implements View.OnClickListener{
private String[] datas;
public MyAdapter(String[] datas) {
this.datas = datas;
}
private OnItemClickListener mOnItemClickListener = null; //define interface
public static interface OnItemClickListener {
void onItemClick(View view , int position);
} @Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
ViewHolder vh = new ViewHolder(view);
//将创建的View注册点击事件
view.setOnClickListener(this);
return vh;
} @Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将position保存在itemView的Tag中,以便点击时进行获取
viewHolder.itemView.setTag(position);
} @Override
public void onClick(View v) {
if (mOnItemClickListener != null) {
//注意这里使用getTag方法获取position
mOnItemClickListener.onItemClick(v,(int)v.getTag());
}
} public void setOnItemClickListener(OnItemClickListener listener) {
this.mOnItemClickListener = listener;
} //获取数据的数量
@Override
public int getItemCount() {
return datas.length;
}
//自定义的ViewHolder,持有每个Item的的所有界面元素
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mTextView;
public ViewHolder(View view){
super(view);
mTextView = (TextView) view.findViewById(R.id.text);
}
}
}
item.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="50dip"
>
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
MainActivity.java
package com.example.recyclerviewdemo; import com.example.recyclerviewdemo.MyAdapter.OnItemClickListener; import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast; public class MainActivity extends ActionBarActivity {
private RecyclerView mRecyclerView;
private LinearLayoutManager mLayoutManager;
private MyAdapter mAdapter;
private String[] data= new String[] {"aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb","aa","bb", "aa","bb", "aa","bb", "aa","bb", "aa","bb" }; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view);
//创建默认的线性LayoutManager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
//如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
mRecyclerView.setHasFixedSize(true);
//创建并设置Adapter
mAdapter = new MyAdapter(data);
mRecyclerView.setAdapter(mAdapter);
mAdapter.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(View view , int position){
Toast.makeText(MainActivity.this, data[position], ).show();
}
});
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} }
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
</RelativeLayout>
总结
在ListView中我们是调用ListView的setOnItemClickListener:
mListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
...
}
});
而在我们这里是调用mAdapter的setOnItemClickListener。
为RecyclerView添加item的点击事件的更多相关文章
- 拦截recyclerview 的item 的点击事件
recyclerview.addOnItemTouchListener(new RecyclerItemClickListener(getActivity(),recyclerview, new Re ...
- Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件
1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...
- 小程序实践(五):for循环绑定item的点击事件
微信展示列表效果借助于 wx:for 简单写一个列表(wxml文件中): 对应的数据源(js文件中): 写一个点击监听: 效果: 以上.可以实现列表的item点击效果,但是无法到点击的item对应的 ...
- android中RecyclerView控件实现点击事件
RecyclerView控件实现点击事件跟ListView控件不同,并没有提供类似setOnItemClickListener()这样的注册监听器方法,而是需要自己给子项具体的注册点击事件. 本文的例 ...
- ExpandableListView实现子Item的点击事件
在继承的BaseExpandableListAdapter的ExpandableListView的Adapter中,重写以下方法 @Override public boolean isChildSel ...
- ListView中响应item的点击事件并且刷新界面
---恢复内容开始--- 最近在在实现listview功能中遇到了这个问题: 点击事件写在了adapter的item中,不知道如何在listview的点击事件中更新数据的显示: 总结:1.要使用not ...
- android listview里包含组件(checkbox)点击事件和Item的点击事件冲突
在listview的item中包含有textview和checkBox.我们既想获取listitem的点击事件,又想获取listitem中textview的点击事件和listitem中checkBox ...
- Qt之添加QLabel的点击事件
QLabel功能为显示了一个字符串或者图片等信息,它本身没有click信号.也就不能够响应click点击事件,有什么办法来实现来,我们可以子类化QLabel,实现MouseXXXEvent.class ...
- React 的 DOM 添加多个点击事件
第一直觉代码如下:后果是写在后面的事件函数覆盖前面的事件函数,只执行第二条(弹出 222). import React, { Component, Fragment } from 'react' ex ...
随机推荐
- HDU 5386 Cover(模拟)
Cover Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Subm ...
- 11.ng-init
转自:https://www.cnblogs.com/best/tag/Angular/ 初始化 <p ng-init="test=1" ng-repeat="a ...
- 线性同余同余方程组解法(excrt)
[问题描述] 求关于 x 的同余方程组 x%a 1 =b 1 a1=b1 x%a 2 =b 2 a2=b2 x%a 3 =b 3 a3=b3 x%a 4 =b 4 a4=b4 的大于等于 0 ...
- 轻松掌握Ubuntu Linux的3D桌面快捷键使用
视频下载地址: http://115.com/file/be4n23v6#linux3d.rar 轻松掌握Ubuntu Linux的3D桌面快捷键使用 高级3D桌面展示 本文出自 "李晨光原 ...
- Codefroces B. T-primes
http://codeforces.com/problemset/problem/230/B B. T-primes time limit per test 2 seconds memory limi ...
- 遇到的兼容性bug
1.(IE6):ie6环境下,通过设置z-index:999:无效果: 原因:IE6下,决定层级高低的不是当前的父标签,而是整个DOM tree(节点树)的第一个relative属性的父标签. 解决办 ...
- 10G安装DataGuard
最后更新时间:2013年8月4日,星期日 ★ oracle 10G安装环境 数据库软件安装环境不详细描述,网上到处有这方面资料,下面只简单描述下. 也可参考官方文档: http://docs.orac ...
- Yeslab 华为安全HCIE七门之-防火墙基础(12篇)
Yeslab 华为安全HCIE七门之-防火墙基础(12篇) Yeslab 全套华为安全HCIE七门之第二门防火墙基础(12篇),第一门课论坛很早就有了,可自行下载,后面的陆续分享给大家. 华为安全HC ...
- CentOS 安装openssl
https://blog.csdn.net/ydyang1126/article/details/72902113 安装环境: 操作系统:CentOS 7 OpenSSL Version:openss ...
- OpenJDK源码研究笔记(十五):吐槽JDK中的10个富有争议的设计
前14篇文章,分享了JDK中值得学习和借鉴的编码和设计方法. 每个硬币都是有两面的.Every coin has two sides. 当然,JDK中也有很多值得改进或者说富有争议的设计. 本篇,就来 ...