一、RecycleView的简介
RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相 似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListView和GridView控件的继承者。 那么有了ListView、GridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManager,ItemDecoration, ItemAnimator实现令人瞠目的效果。
- 你想要控制其显示的方式,请通过布局管理器LayoutManager
- 你想要控制Item间的间隔(可绘制),请通过ItemDecoration
- 你想要控制Item增删的动画,请通过ItemAnimator
- 你想要控制点击、长按事件,请自己写(擦,这点尼玛。)
二、RecycleView的基本使用 1、在Gradle中引入RecycleView的依赖库。 compile 'com.android.support:recyclerview-v7:23.1.1' 2、在布局文件当中放置我们的RecycleView。 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <android.support.v7.widget.RecyclerView android:id="@+id/recycle" android:layout_width="match_parent" android:layout_height="wrap_content"/> </LinearLayout> 3、创建适配器类继承RecycleView的Adapter,步骤为:
- 继承RecyclerView.Adapter,并且在Adapter里面声明ViewHolder类继承RecyclerView.ViewHolder,最后把自己的ViewHolder类丢进自己的Adapter类的泛型中去。
- 在自定义ViewHolder类的构造方法中可以通过ID找到布局的控件,控件需要声明为自定义ViewHolder类的成员变量。
- 实现RecyclerView.Adapter的所有未实现的函数,onCreateViewHolder主要负责加载布局(加载的时候注意要把父布局写到参数里去),创建自定义ViewHolder类的对象;onBindViewHolder主要负责把数据设置到Item的控件中;getItemCount主要负责得到数据的数目。
- 最好把数据声明为成员变量,在构造函数里面传进来。
- 由于RecycleView原生不支持点击事件,需要自己添加接口进行回调。
代码如下: public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> { List<String> mDatas = null; Context mContext = null; //通过构造函数把要显示的数据读取进来 public MyAdapter(List<String> mDatas, Context context) { this.mDatas = mDatas; this.mContext = context; } //相当于ListView中的getView()方法 @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { // View v = View.inflate(mContext,R.layout.item, null); LayoutInflater inflater = LayoutInflater.from(mContext); //加载布局的时候需要注意要把parent传进去 View v = inflater.inflate(R.layout.layout_item, parent, false); MyViewHolder holder = new MyViewHolder(v); return holder; } //在这里需要设置显示的数据 @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.tv_num.setText(mDatas.get(position)); } @Override public int getItemCount() { return mDatas.size(); } //自定义ViewHolder必须继承RecyclerView.ViewHolder,在构造函数中进行ID绑定控件,条目监听等 class MyViewHolder extendsRecyclerView.ViewHolder { TextView tv_num; public MyViewHolder(final View itemView) { super(itemView); tv_num = (TextView) itemView.findViewById(R.id.tv_num); tv_num.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { onItemClickListener.onItemClick(itemView, getLayoutPosition(), mDatas.get(getLayoutPosition())); } } }); } } //自定义监听 private OnItemClickListener onItemClickListener; public void setOnItemClickListener(OnItemClickListener listener) { this.onItemClickListener = listener; } public interface OnItemClickListener { void onItemClick(View v, int position, String data); } public void addData(int position, String data) { mDatas.add(position, data); notifyItemInserted(position); } public void removeData(int position) { mDatas.remove(position); notifyItemRemoved(position); } }
4、下面是MainActivity中需要进行的处理。核心的步骤(某些步骤可不分先后)如下:
- 通过ID找到RecyclerView。
- RecyclerView设置Adapter。
- RecyclerView设置布局管理器,常用的布局管理器有LinearLayoutManager:线性布局,LayoutManager的实现类,类型包括Vertical和HorizontalGridLayoutManager;格子布局,继承自LinearLayoutManager,实现效果类似GridView;StaggeredGridLayoutManager交错的格子布局,同样也是LayoutManager的实现类,类型包括Vertical和Horizontal,与GridLayoutManager很相似,不过是交错的格子,也就是宽高不等的格子视图,类似瀑布流的效果。
- RecyclerView设置数据插入、删除的时候的动画效果,这里使用默认的。下面的网址是GitHub上面的开源动画效果:https://github.com/gabrielemariotti/RecyclerViewItemAnimators
- RecyclerView设置Item之间的装饰器,这里也是使用GitHub提供的装饰器,代码会在附件中给出。
代码如下: public class MainActivity extendsAppCompatActivity { List<String> datas = null; private RecyclerView recyclerView; private MyAdapter myAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); recyclerView = (RecyclerView) findViewById(R.id.recycle); //设置RecycleView的适配器 myAdapter = new MyAdapter(datas, this); recyclerView.setAdapter(myAdapter); //设置布局管理器,以渲染出不同的效果 recyclerView.setLayoutManager(new LinearLayoutManager(this)); //设置插入、删除数据的动画效果(这里使用默认的动画) recyclerView.setItemAnimator(new DefaultItemAnimator()); //设置每个Item之间的装饰(这里设置为分隔线) recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); //设置条目监听,需要自定义接口 myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() { @Override public void onItemClick(View v, int position, String data) { Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show(); } }); } private void initData() { datas = new ArrayList<>(); for (int i = 0; i < 300; i++) { datas.add(i + ""); } } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_main, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.action_add: myAdapter.addData(0, "new data"); recyclerView.scrollToPosition(0); break; case R.id.action_delete: myAdapter.removeData(0); break; case R.id.action_gridview: recyclerView.setLayoutManager(new GridLayoutManager(this, 4)); break; case R.id.action_listview: recyclerView.setLayoutManager(new LinearLayoutManager(this)); break; case R.id.action_staggeredgridview: recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL)); break; } return true; } }
三、运行效果
先上图三张,具体的一些动画效果需要自己体会。
对啦,notifyDataSetChanged方法以及弃用了,请注意RecycleView的新规矩:
notifyDataSetChanged()弃用
notifyItemChanged(intposition)
notifyItemInserted(intposition)
notifyItemMoved(intfromPosition, int toPosition)
notifyItemRemoved(intposition)
//range系列,多个item的操作
notifyItemRangeChanged(intpositionStart, int itemCount)
notifyItemRangeInserted(intpositionStart, int itemCount)
notifyItemRangeRemoved(intpositionStart, int itemCount)
补充:可以通过Adapter的getViewType(intposition)方法实现多种不同的条目。
具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可。
如下图所示:
|