概述
RecyclerView出现在Android 5中 需要引进support-v7包内
构成
一个RecyclerView由六个成分
Adapter:提供数据,为每个Item创建视图(相似于ListView)ItemAnimator:负责添加、移动、移除的动画效果ItemDecoration:为每个Item视图添加子视图(e.g. 添加分割线)LayoutManager:负责Item视图的布局管理器(一个线性布局,类似于ListView;一个网格布局;一个瀑布流式布局)ViewHolder:承载Item视图的子视图RecyclerView本身:一起绑定任何事务
展示一个RecyclerView
准备你的project
- 如果你使用Gradle,添加你的dependencies
compile 'com.android.support:recyclerview-v7:25.1.0' - 使用
CardView同样添加依赖
compile 'com.android.support:cardview-v7:25.1.0'
Adapter
- 第一步:声明
ViewHolder类,它必须继承RecyclerView.ViewHolder,在这里有两个TextView(ViewHolder不了解,阅读Hold View Objects in a View Holder)
public static class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
TextView subtitle;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
subtitle = (TextView) itemView.findViewById(R.id.subtitle);
}
}
- 第二步:
Adapter负责扮演两个角色,不仅为底部数据提供支持而且还负责为数据创建合适的视图。
- 继承
RecyclerView.Adapter需要实现以下三个方法
public ViewHolder onCreateViewHolder(ViewGroup parent,int viewType):创建一个视图然后返回一个正在匹配的ViewHolderpublic void onBindViewHolder(ViewHolder holder,int position): 绑定View,根据返回的position类型,从而进行绑定到ViewHolder上public int getItemCount():返回View中Item的个数
- 有需求才实现的方法
public int getItemViewType(int position):判断item的类型,从而绑定不同的view
- 继承
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<String> mDatas;
public MyAdapter(List<String> list) {
this.mDatas = list;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View layout = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ListHolder(layout);
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ListHolder) holder).tv.setText(mDatas.get(position));
}
@Override
public int getItemCount() {
return mDatas.size();
}
class ListHolder extends RecyclerView.ViewHolder {
TextView tv;
public ListHolder(View itemView) {
super(itemView);
tv = (TextView) itemView.findViewById(R.id.item);
}
}
}
RecyclerView.LayoutManager
- LinearLayoutManager提供了横向和竖向两种布局。默认是
LinearLayout.VERTICAL - LinearLayoutManager提供以下几个方法获取屏幕上的顶部item和底部item
findFirstVisibleItemPosition()findFirstCompletelyVisibleItemPosition()findLastVisibleItemPosition()findLastCompletelyVisibleItemPosition()
RecyclerView.ItemDecoration
通过ItemDecoration可以使各个Item在视觉上相互分开,其实和ListView的Divider很像。ItemDecoration并不是RecyclerView必须设置的,开发者可以不设置或者设置多个Decoration。RecyclerView会遍历所有的ItemDecoration并调用各自的绘图方法。
继承RecyclerView.ItemDecoration需要实现以下方法:
public void onDraw(Canvas c,RecyclerView parent,RecyclerView.State state)public void getItemOffset(Rect outRect,int itemPosition,RecyclerView parent):调用getItemOffset方法来计算每个Item的Decoration合适的尺寸。
RecyclerView.ItemAnimator
当Item有以下三种操作时RecyclerView所提供的动画效果:删除、添加、移动。
Google提供了一个名为DefaultItemAnimator的默认ItemAnimator供开发者使用。如果开发者不为RecyclerView设置ItemAnimator,RecyclerView也会使用默认的DefaultItemAnimator。
显然,为了让动画效果起效,开发者必须通知Adapter数据有改变。之前我们使用Adapter时会调用notifyDataSetChanged()来通知Adapter数据改变并更新视图,现在RecyclerView,Adapter提供了许多notifyItemXXX()方法:
notifyItemChanged(int position)notifyItemInserted(int position)notifyItemRemoved(int position)notifyItemMoved(int fromPosition, int toPosition)notifyItemRangeChanged(int positionStart, int itemCount)notifyItemRangeInserted(int positionStart, int itemCount)notifyItemRangeRemoved(int positionStart, int itemCount)notifyDataSetChanged()
使用RecyclerView
- 第一步:添加RecyclerView在Activity的布局上
<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/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
- 第二步
mRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));//设置布局mRecyclerView.setItemAnimator(new DefaultItemAnimator());//设置动画(非必需)mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));//设置分割线(非必需)mRecyclerView.setAdapter(mAdapter = new MyAdapter(mDatas));//设置Adapter
public class demo2 extends AppCompatActivity {
private RecyclerView mRecyclerView;
private MyAdapter mMyAdapter;
private List<String> mList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo2);
//RecyclerView三部曲+LayoutManager
mRecyclerView = (RecyclerView)findViewById(R.id.rv_demo2);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(linearLayoutManager);
initData();
mMyAdapter = new MyAdapter(mList);
mRecyclerView.setAdapter(mMyAdapter);
}
//初始化RecyclerView中每个item的数据
private void initData(){
mList = new ArrayList<String>();
for (int i = 0; i < 20; i++){
mList.add("item" + i);
}
}
附加功能
添加点击事件
第一种(在Adapter内添加)
public interface OnItemClickListener{
void onItemClick(View view, int position);
}
public interface OnItemLongClickListener{
void onItemLongClick(View view, int position);
}
private OnItemClickListener mOnItemClickListener;
private OnItemLongClickListener mOnItemLongClickListener;
//设置Item点击监听
public void setOnItemClickListener(OnItemClickListener mOnItemClickListener){
this.mOnItemClickListener = mOnItemClickListener;
}
public void setOnItemLongClickListener(OnItemLongClickListener mOnItemLongClickListener) {
this.mOnItemLongClickListener = mOnItemLongClickListener;
}
public MyAdapter(List<String> data) {
this.mDatas = data;
}
//创建Item视图,并返回相应的ViewHolder
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder myViewHolder = new MyViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_single_textview,parent,false));
return myViewHolder;
}
//绑定数据到正确的Item视图上
@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.textView.setText(mDatas.get(position));
// 如果设置了回调,则设置点击事件
if (mOnItemClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = holder.getLayoutPosition();
mOnItemClickListener.onItemClick(holder.itemView,position);
}
});
}
holder.itemView.setOnLongClickListener(new View.OnLongClickListener()
{
@Override
public boolean onLongClick(View v)
{
int position = holder.getLayoutPosition();
mOnItemLongClickListener.onItemLongClick(holder.itemView,position);
//返回true 表示消耗了事件 事件不会继续传递
return true;
}
});
}
第二种(在ViewHolder内和在Activity内)
ViewHolder应用View.OnClickListener和View.OnLongClickListener
public class Adapter extends SelectableAdapter<Adapter.ViewHolder> {
// …
private ViewHolder.ClickListener clickListener;
public Adapter(ViewHolder.ClickListener clickListener) {
super();
this.clickListener = clickListener;
}
/**
* public void setOnItemClickListener(MyItemClickListener listener){
this.mItemClickListener = listener;
}
* 有此方法 Activity中onCreate内需要初始化下面已给出
**/
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
final int layout = viewType == TYPE_INACTIVE ? R.layout.item : R.layout.item_active;
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
return new ViewHolder(v, clickListener);
}
// …
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
View.OnLongClickListener {
TextView title;
TextView subtitle;
View selectedOverlay;
private ClickListener listener;
public ViewHolder(View itemView, ClickListener listener) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.title);
subtitle = (TextView) itemView.findViewById(R.id.subtitle);
selectedOverlay = itemView.findViewById(R.id.selected_overlay);
this.listener = listener;
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
@Override
public void onClick(View v) {
if (listener != null) {
listener.onItemClicked(getPosition());
}
}
@Override
public boolean onLongClick(View v) {
if (listener != null) {
return listener.onItemLongClicked(getPosition());
}
return false;
}
public interface ClickListener {
public void onItemClicked(int position);
public boolean onItemLongClicked(int position);
}
}
}
Activity内(继承ViewHolder的ClickListener)
- 初始化 (onCreate内)
this.mAdapter.setOnItemClickListener(this);this.mAdapter.setOnItemLongClickListener(this);
- 初始化 (onCreate内)
@Override
public void onItemClick(View view, int postion) {
MyItemBean bean = mData.get(postion);
if(bean != null){
Toast.makeText(this, bean.tv, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onItemLongClick(View view, int postion) {
MyItemBean bean = mData.get(postion);
if(bean != null){
Toast.makeText(this, "LongClick "+bean.tv, Toast.LENGTH_SHORT).show();
}
}
添加Header和Footer
=========================更新中
Github地址
资料来源
RecyclerView basics
Android RecyclerView 使用完全解析 体验艺术般的控件
Android-RecylerView初识
本文详细介绍了RecyclerView的组成部分及其使用方法,包括Adapter、ViewHolder等核心组件的作用,LayoutManager的布局方式,ItemDecoration和ItemAnimator的效果实现,以及如何在项目中配置RecyclerView。
1506

被折叠的 条评论
为什么被折叠?



