RecyclerView的那点事儿
RecyclerView
控件简单介绍
- ListView的升级版
- LinearLayoutManager
- GridLayoutManager
- StaggeredGridLayoutManager
- 定制Item动画,指定Item之间的分隔线
RecyclerView相关的重要类
- Adapter
- ViewHolder
- LayoutManager
- ItemDecoration
- ItemAnimator
加入RecyclerView控件依赖包
Android Studio开发工具,在本项目的build.gradle文件里加入
compile 'com.android.support:recyclerview-v7:23.1.1'
假设是eclipse的话,下载jar包。放到lib下。一般都会自己主动的build path,检查下就可以。
怎样下载jar ?
在SDK Manager中下载Support Library
sdk\extras\android\support\v7\recyclerview\libs
为Recycler准备数据
package demo.turing.com.materialdesignwidget.recyclerView;
import java.util.ArrayList;
import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-30 20:21.
* @version 1.0
* @desc
*/
public class SimulatorData {
public static ArrayList<SampleModel> getSampleModelData(int size) {
ArrayList<SampleModel> sampleData = new ArrayList<SampleModel>(size);
for (int i = 0; i < size; i++) {
sampleData.add(new SampleModel("新的列表项< " + i + " >"));
}
return sampleData;
}
}
package demo.turing.com.materialdesignwidget.recyclerView.model;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-30 20:23.
* @version 1.0
* 相应Item中药显示的数据项
*/
public class SampleModel {
private String text;
public SampleModel(String text) {
this.text = text;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
绘制列表项之间的分隔线
package demo.turing.com.materialdesignwidget.recyclerView;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-30 20:37.
* @version 1.0
* 分隔条
*
*
* DividerItemDecoration https://gist.github.com/alexfu/0f464fc3742f134ccd1e
*/
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
// 默认分隔条Drawable资源的ID,使用系统自带的
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mDivider;
private int mOrientation;
public DividerItemDecoration(Context context, int orientation) {
// 使用TypedArray装载定义的ATTRS
final TypedArray a = context.obtainStyledAttributes(ATTRS);
// 获取系统提供的分隔条Drawable对象
mDivider = a.getDrawable(0);
// 回收TypedArray所占用的空间
a.recycle();
setOrientation(orientation);
}
/**
* 设置item的显示 水平 or 垂直
*
* @param orientation
*/
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException("invalid orientation");
}
mOrientation = orientation;
}
@Override
public void onDraw(Canvas c, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
RecyclerView v = new android.support.v7.widget.RecyclerView(
parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomMargin;
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightMargin;
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
@Override
public void getItemOffsets(Rect outRect, int itemPosition,
RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}
实现Adapter
package demo.turing.com.materialdesignwidget.recyclerView.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;
import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-30 21:03.
* @version 1.0
* @desc
*/
public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {
// 模拟数据
private ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
/**
* 用于创建控件
*
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// 获得列表项控件(LinearLayer对象)
// list_basic_item.xml布局文件里仅仅包括一个<LinearLayer>标签,
// 在该标签中包括了一个<TextView>标签, item是LinearLayout对象
View item = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_basic_item, parent, false);
ViewHolder viewHolder = new ViewHolder(item);
return viewHolder;
}
/**
* 为控件设置数据
*
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
// 获取当前item中显示的数据
final SampleModel rowData = sampleData.get(position);
// 设置要显示的数据
holder.textViewSample.setText(rowData.getText());
// 设置tag
holder.itemView.setTag(rowData);
}
@Override
public int getItemCount() {
return sampleData.size();
}
/**
* 删除指定的Item
*
* @param position
*/
public void removeData(int position) {
sampleData.remove(position);
// 通知RecyclerView控件某个Item已经被删除
notifyItemRemoved(position);
}
/**
* 在指定位置加入一个新的Item
*
* @param positionToAdd
*/
public void addItem(int positionToAdd) {
sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
// 通知RecyclerView控件插入了某个Item
notifyItemInserted(positionToAdd);
}
/**
* 相应Item中的控件
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textViewSample;
public ViewHolder(View itemView) {
super(itemView);
textViewSample = (TextView) itemView
.findViewById(R.id.textViewSample);
}
}
}
完毕使用RecyclerView控件的最后工作
package demo.turing.com.materialdesignwidget.recyclerView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;
public class RecyclerViewAct extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
// 获取RecyclerView对象
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
// 创建线性布局管理器(默认是垂直方向)
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
// 为RecyclerView指定布局管理对象
recyclerView.setLayoutManager(layoutManager);
// 创建列表项分隔线对象
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);
// 为RecyclerView控件指定分隔线对象
recyclerView.addItemDecoration(itemDecoration);
SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();
recyclerView.setAdapter(sampleRecyclerAdapter);
}
}
效果图
定制个性化分隔条
drawable\divider_custom.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<size android:height="4dp"></size>
<!--渐变色-->
<gradient
android:centerColor="#ff0000ff"
android:endColor="#ffff0000"
android:startColor="#ffff0000"
android:type="linear"></gradient>
</shape>
主题中设置
<item name="android:listDivider">@drawable/divider_custom</item>
瀑布流
StaggeredGridLayuoutAct.java
package demo.turing.com.materialdesignwidget.recyclerView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import java.util.List;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.adapter.StaggeredGridLayoutAdapter;
import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
/**
* 不採用分隔线, 在Item的布局中 採用layout_margin的方式
*
* 主要是动态设置View的高度 adapter类中的 onBindViewHolder
*/
public class StaggeredGridLayuoutAct extends AppCompatActivity {
private RecyclerView recyclerView ;
// 模拟数据
private List<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_staggered_grid_layuout);
// 查找组件
recyclerView = (RecyclerView) findViewById(R.id.id_rv_staggered);
// 创建布局管理器 -3列,垂直
StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
// 设置布局
recyclerView.setLayoutManager(manager);
// Adapter
StaggeredGridLayoutAdapter adapter = new StaggeredGridLayoutAdapter(this,sampleData);
recyclerView.setAdapter(adapter);
}
}
activity_staggered_grid_layuout.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="demo.turing.com.materialdesignwidget.recyclerView.StaggeredGridLayuoutAct">
<android.support.v7.widget.RecyclerView
android:id="@+id/id_rv_staggered"
android:layout_width="match_parent"
android:layout_height="match_parent"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
StaggeredGridLayoutAdapter.java
package demo.turing.com.materialdesignwidget.recyclerView.adapter;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-31 20:19.
* @version 1.0
* @desc
*/
public class StaggeredGridLayoutAdapter extends RecyclerView.Adapter<StaggeredGridLayoutAdapter.ViewHolder> {
private Context context;
private List<SampleModel> datas;
private LayoutInflater inflater;
// 随机高度的结合
private List<Integer> mHeights;
/**
* 构造函数
*
* @param context
* @param datas
*/
public StaggeredGridLayoutAdapter(Context context, List<SampleModel> datas) {
this.context = context;
this.datas = datas;
this.inflater = LayoutInflater.from(context);
// 初始化随机高度的集合
mHeights = new ArrayList<>();
for (int i = 0; i < datas.size(); i++) {
mHeights.add((int)(100 + Math.random() * 300));
}
}
@Override
public StaggeredGridLayoutAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// 动态载入Item的布局文件
View view = inflater.inflate(R.layout.list_basic_item, parent, false);
// 实例化ViewHolder
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(StaggeredGridLayoutAdapter.ViewHolder holder, int position) {
// 获取当前Item中的显示的数据
SampleModel sampleModel = datas.get(position);
//设置控件的随机高度
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
lp.height = mHeights.get(position);
holder.itemView.setLayoutParams(lp);
// 设置组件的值
holder.textView.setText(sampleModel.getText());
// 设置tag
holder.itemView.setTag(sampleModel);
}
@Override
public int getItemCount() {
return datas.size();
}
/**
* ViewHoder
*/
class ViewHolder extends RecyclerView.ViewHolder {
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
textView = (TextView) itemView
.findViewById(R.id.textViewSample);
}
}
}
list_basic_item.xml
<?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="match_parent"
android:layout_margin="3dp"
android:background="#6495ED"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:id="@+id/textViewSample"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="演示"/>
</RelativeLayout>
效果图
动画效果
// 默认动画效果
recyclerView.setItemAnimator(new DefaultItemAnimator());
notifyItemRemoved(position)
/**
* 删除指定的Item
*
* @param position
*/
public void removeData(int position) {
sampleData.remove(position);
// 通知RecyclerView控件某个Item已经被删除
notifyItemRemoved(position);
}
notifyItemInserted(positionToAdd)
/**
* 在指定位置加入一个新的Item
*
* @param positionToAdd
*/
public void addItem(int positionToAdd) {
sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
// 通知RecyclerView控件插入了某个Item
notifyItemInserted(positionToAdd);
}
为RecyclerView加入item的点击事件
方法一:利用回调的方式实现(不太完好,仍可实现)
实现过程例如以下:
在adapter类中,定义接口,接口中定义两个方法分别相应click和longClick,定义完接口。加入接口和设置Adapter接口的方法:
/**
* 接口 ,提供两个方法
*/
public interface OnRecyclerViewItemClickListener{
// 单击事件
void onItemClick(View view ,int position);
// 长按触发的事件
void onItemLongClick(View view ,int position);
}
// 定义OnRecyclerViewItemClickListener对象
public OnRecyclerViewItemClickListener mOnRecyclerViewItemClickListener ;
// 暴漏给外部的set方法。持有OnRecyclerViewItemClickListener对象
public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){
this.mOnRecyclerViewItemClickListener = listener ;
}
在onBindViewHolder方法中
// 点击事件
if(mOnRecyclerViewItemClickListener != null){
// click
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,position);
}
});
// longClick
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,position);
return false;
}
});
}
做完这些事情,我们就能够在Activity或其它地方为RecyclerView加入项目点击事件了,
// 设置监事件
sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();
}
});
完整代码例如以下:
RecyclerViewAct
package demo.turing.com.materialdesignwidget.recyclerView;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Toast;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.adapter.SampleRecyclerAdapter;
public class RecyclerViewAct extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler_view);
// 获取RecyclerView对象
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view);
// 创建线性布局管理器(默认是垂直方向)
LinearLayoutManager layoutManager = new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false);
// 为RecyclerView指定布局管理对象
recyclerView.setLayoutManager(layoutManager);
// 创建列表项分隔线对象
RecyclerView.ItemDecoration itemDecoration = new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST);
// 为RecyclerView控件指定分隔线对象
recyclerView.addItemDecoration(itemDecoration);
// 默认动画效果
recyclerView.setItemAnimator(new DefaultItemAnimator());
SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter();
recyclerView.setAdapter(sampleRecyclerAdapter);
// 设置监事件
sampleRecyclerAdapter.setOnRecyclerViewItemClickListener(new SampleRecyclerAdapter.OnRecyclerViewItemClickListener() {
@Override
public void onItemClick(View view, int position) {
Toast.makeText(RecyclerViewAct.this,"Click" + position ,Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(View view, int position) {
Toast.makeText(RecyclerViewAct.this,"LongClick" + position ,Toast.LENGTH_SHORT).show();
}
});
}
}
SampleRecyclerAdapter
package demo.turing.com.materialdesignwidget.recyclerView.adapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Random;
import demo.turing.com.materialdesignwidget.R;
import demo.turing.com.materialdesignwidget.recyclerView.SimulatorData;
import demo.turing.com.materialdesignwidget.recyclerView.model.SampleModel;
/**
* MyApp
*
* @author Mr.Yang on 2016-03-30 21:03.
* @version 1.0
* @desc
*
*
* RecyclerView 点击事件 请看http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1118/2004.html
*/
public class SampleRecyclerAdapter extends RecyclerView.Adapter<SampleRecyclerAdapter.ViewHolder> {
// 模拟数据
private ArrayList<SampleModel> sampleData = SimulatorData.getSampleModelData(20);
/**
* 接口 ,提供两个方法
*/
public interface OnRecyclerViewItemClickListener{
// 单击事件
void onItemClick(View view ,int position);
// 长按触发的事件
void onItemLongClick(View view ,int position);
}
// 定义OnRecyclerViewItemClickListener对象
public OnRecyclerViewItemClickListener mOnRecyclerViewItemClickListener ;
// 暴漏给外部的set方法。持有OnRecyclerViewItemClickListener对象
public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){
this.mOnRecyclerViewItemClickListener = listener ;
}
/**
* 用于创建控件
*
* @param parent
* @param viewType
* @return
*/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// 获得列表项控件(LinearLayer对象)
// list_basic_item.xml布局文件里仅仅包括一个<LinearLayer>标签,
// 在该标签中包括了一个<TextView>标签, item是LinearLayout对象
View item = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_basic_item, parent, false);
ViewHolder viewHolder = new ViewHolder(item);
return viewHolder;
}
/**
* 为控件设置数据
*
* @param holder
* @param position
*/
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// 获取当前item中显示的数据
final SampleModel rowData = sampleData.get(position);
// 设置要显示的数据
holder.textViewSample.setText(rowData.getText());
// 设置tag
holder.itemView.setTag(rowData);
// 点击事件
if(mOnRecyclerViewItemClickListener != null){
// click
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 通过getLayoutPosition,防止position错位
int layoutPosition = holder.getLayoutPosition();
mOnRecyclerViewItemClickListener.onItemClick(holder.itemView,layoutPosition);
}
});
// longClick
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
int layoutPosition = holder.getLayoutPosition();
mOnRecyclerViewItemClickListener.onItemLongClick(holder.itemView,layoutPosition);
return false;
}
});
}
}
@Override
public int getItemCount() {
return sampleData.size();
}
/**
* 删除指定的Item
*
* @param position
*/
public void removeData(int position) {
sampleData.remove(position);
// 通知RecyclerView控件某个Item已经被删除
notifyItemRemoved(position);
}
/**
* 在指定位置加入一个新的Item
*
* @param positionToAdd
*/
public void addItem(int positionToAdd) {
sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000)));
// 通知RecyclerView控件插入了某个Item
notifyItemInserted(positionToAdd);
}
/**
* 相应Item中的控件
*/
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textViewSample;
public ViewHolder(View itemView) {
super(itemView);
textViewSample = (TextView) itemView
.findViewById(R.id.textViewSample);
}
}
}
方法二:使用观察者模式实现
原理:
为RecyclerView的每一个子item设置setOnClickListener。然后在onClick中再调用一次对外封装的接口。将这个事件传递给外面的调用者。而“为RecyclerView的每一个子item设置setOnClickListener”在Adapter中设置。事实上直接在onClick中也能全然处理item的点击事件,可是这样会破坏代码的逻辑。
步骤
在自己定义的adapter(记得implements View.OnClickListener,以下有个onClick方法)中定义例如以下接口,模拟ListView的OnItemClickListener:
//define interface
public static interface OnRecyclerViewItemClickListener {
void onItemClick(View view , String data);
}
声明一个这个接口的变量:
private OnRecyclerViewItemClickListener 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方法获取数据
mOnItemClickListener.onItemClick(v,(String)v.getTag());
}
}
意上面调用接口的onItemClick()中的v.getTag()方法,这须要在onBindViewHolder()方法中设置和item相关的数据
@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
viewHolder.mTextView.setText(datas[position]);
//将数据保存在itemView的Tag中,以便点击时进行获取
viewHolder.itemView.setTag(datas[position]);
}
最后暴露给外面的调用者,定义一个设置Listener的方法():
public void setOnItemClickListener(OnRecyclerViewItemClickListener 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 OnRecyclerViewItemClickListener(){
@Override
public void onItemClick(View view , String data){
Toast.makeText(MainActivity.this, data, 600).show();
}
});
RecyclerView加入Header
RecyclerView的那点事儿的更多相关文章
- RecyclerView再封装
RecyclerView做为ListView的替代品,已经出了很久了,既然是替代品,那自然有些ListView没有的优点.比如说:可以随意切换list,grid,stagger.可以指定一个或多个it ...
- 说说Makefile那些事儿
说说Makefile那些事儿 |扬说|透过现象看本质 工作至今,一直对Makefile半知半解.突然某天幡然醒悟,觉得此举极为不妥,只得洗心革面从头学来,以前许多不明觉厉之处顿时茅塞顿开,想想好记性不 ...
- RecyclerView使用大全
RecylerView介绍 RecylerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字recyler ...
- 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载
title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...
- 安卓易学,爬坑不易——腾讯老司机的RecyclerView局部刷新爬坑之路
针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验.目前功能还在免费开放中. 点击地址:http://wetest ...
- Android Studio开发RecyclerView遇到的各种问题以及解决(二)
开发RecyclerView时候需要导入别人的例子,我的是从github导入的,下载下github的压缩包之后解压看你要导入的文件是priject还是Module.(一般有app文件夹的大部分是pro ...
- Android Studio开发RecyclerView遇到的各种问题以及解决(一)
以前一直在用ListView,,,最近才看RecyclerView发现好强大.RecyclerView前提是Android版本在5.0以上,本人以前用的是eclipse只支持到4.4.索性就安装一个A ...
- Android的Kotlin秘方(II):RecyclerView 和 DiffUtil
作者:Antonio Leiva 时间:Sep 12, 2016 原文链接:http://antonioleiva.com/recyclerview-diffutil-kotlin/ 如你所知,在[支 ...
- 总结iOS开发中的断点续传那些事儿
前言 断点续传概述 断点续传就是从文件赏赐中断的地方重新开始下载或者上传数据,而不是从头文件开始.当下载大文件的时候,如果没有实现断点续传功能,那么每次出现异常或者用户主动的暂停,都会从头下载,这样很 ...
随机推荐
- JavaWeb学习总结(十二)——Session(转)
一.Session简单介绍 在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下).因此,在需要保存用户数据时,服务 ...
- gulp前端自动化入门
一.从零开始搭建gulp前端自动化 1.首先安装nodejs 2.npm init 初始化 生成package.json 2.1 可以选装cnpm cnpm是淘宝提供的服务 安装:命令提示符执行npm ...
- polyfill for Function--源码
/** * polyfill for Function */ // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer ...
- 常用的XMPP服务器
1. Openfire (Wildfire) 3.x 底层通讯采用的mina框架,minak框架其实性能一般,netty早已经超越它,虽然最初都是Doug Lea写的.3.4版本之后支持集群,单台服务 ...
- 标准C程序设计七---53
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- kafka性能调优
https://blog.csdn.net/u013063153/article/details/73826322
- luogu P1922 女仆咖啡厅桌游吧
题目背景 小v带萌萌的妹妹去玩,妹妹想去女仆咖啡馆,小v想去桌游吧. 妹妹:“我问你个问题,答不对你就做我一天的奴隶,答对了就今天我就全部听你的.” 小v:“全部都听!?” 妹妹:“嘻嘻嘻,你还是回答 ...
- luogu P1197 [JSOI2008]星球大战
题目描述 很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系.某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球.这些星球通过特殊的以太隧道 ...
- Spring Boot中使用AOP记录请求日志
这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...
- Linux下快速删除输错的密码技巧(快速删除输入的命令)
1.[Esc]+[退格键(Backspace)] 2.[Ctrl]+[U] 说明:以上两个快捷键都会删除全部输错的命令或密码. 参考: http://blog.csdn.net/u013895662/ ...