黑马程序员技术交流社区

标题: 【济南校区】凯哥兵法之RecyclerView [打印本页]

作者: 孟凡凯老师    时间: 2016-5-15 22:33
标题: 【济南校区】凯哥兵法之RecyclerView
本帖最后由 孟凡凯老师 于 2016-5-15 22:39 编辑

【济南校区】凯哥兵法之RecyclerView
概述:
  RecyclerView是ListView的升级版,它具备了更好的性能,且更容易使用。和ListView一样,RecyclerView是用来显示大量数据的容器,并通过复用有限数量的View,来提高滚动时的性能。当你的视图上的元素经常动态的且有规律的改变时候,可以使用RecyclerView控件。
与ListView不同的是RecyclerView现在不再负责布局,只专注于复用机制,布局交由LayoutManager来管理。 RecyclerView仍然通过Adapter来获取需要显示的对象。
使用:
在布局中引入v7包中的RecyclerView
  1. <android.support.v7.widget.RecyclerView
  2.   android:layout_width="match_parent"
  3.   android:layout_height="match_parent"
  4.   android:id="@+id/recycler" />
复制代码
在代码找到RecyclerView
  1. mRrecyclerView = (RecyclerView) findViewById(R.id.recycler);
复制代码
ListView的用法:
  1. // LinearLayoutManager  布局管理者可以将每个条目的视图放置于适当的位置。
  2. LinearLayoutManager   layoutManager = new LinearLayoutManager (this);
  3. //设置布局的方向 LinearLayoutManager.VERTICAL:垂直;LinearLayoutManager.HORIZONTAL:水平;
  4. layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  5. //给RrecyclerView设置布局管理者
  6. mRrecyclerView.setLayoutManager(layoutManager);
  7. //设置RrecyclerView适配器。
  8. mRrecyclerView.setAdapter(new MyListAdapter(getApplication(),mList));
  9. //设置RrecyclerView背景颜色
  10. mRrecyclerView.setBackgroundColor(Color.parseColor("#eeeeee"));
  11. //设置RrecyclerView条目的动画
  12. mRrecyclerView.setItemAnimator(new DefaultItemAnimator());
复制代码
下面是RecyclerView的适配器,要使用RecyclerView组件,创建Adapter不再继承自BaseAdapter,而是应该继承自RecyclerView.Adapter类,并且最好指定一个继承自RecyclerView.ViewHolder的范型,Adapter不再要求你返回一个View,而是一个ViewHolder。需要实现三个方法:
public ListHolder onCreateViewHolder(ViewGroup parent, int viewType) 当RecyclerView需要一个ViewHolder时会回调该方法,如果有可复用的View不会回调该方法
public void onBindViewHolder(ListHolder  holder, int position) 当一个View需要出现在屏幕上时,该方法会被回调,可以在该方法中根据数据来更改视图
public int getItemCount()返回RecycleView有多少条目
  1. public class MyListAdapter extends RecyclerView.Adapter<MyListAdapter.ListHolder> {
  2.     private Context mContext;
  3.     private ArrayList<String> mList;
  4.     public MyListAdapter(Context context , ArrayList<String> list){
  5.         this.mContext = context;
  6.         this.mList=list;
  7.     }
  8. /** 类似BaseAdapter中的getView()方法*/
  9.     @Override
  10.     public ListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  11.         View view = LayoutInflater.from(mContext).inflate( R.layout.item_list, parent, false);
  12.         return new ListHolder(view) ;
  13.     }
  14.     /**一般是用来进行绑定数据*/
  15.     @Override
  16.     public void onBindViewHolder(ListHolder holder, int position) {
  17.         holder.setData(position);
  18.     }
  19.     /**返回RecycleView有多少条目*/
  20.     @Override
  21.     public int getItemCount() {
  22.         return mList.size();
  23.     }
复制代码
效果图如下:
GirdView的用法:
  1. // 创建布局管理,需要传入两个参数,第一个参数是Context上下文对象,第二个是GridView需要展示的列数。
  2. GridLayoutManager  layoutManager = new GridLayoutManager(getApplicationContext(),3);
  3. //设置布局的方向
  4. layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
  5. //给RrecyclerView设置布局管理者
  6. mRrecyclerView.setLayoutManager(layoutManager);
  7. //设置RrecyclerView适配器。
  8. mRrecyclerView.setAdapter(new MyListAdapter(getApplication(),mList));
  9. //设置RrecyclerView背景颜色
  10. mRrecyclerView.setBackgroundColor(Color.parseColor("#eeeeee"));
  11. //设置RrecyclerView条目的动画
  12. mRrecyclerView.setItemAnimator(new DefaultItemAnimator());
复制代码

效果图如下:



StaggeredGrid(瀑布流)的用法:
  1.         // 创建布局管理,需要传入两个参数,第一个参数是StaggeredGrid需要展示的列数,第二个是布局的方向。
  2.         StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2,LinearLayoutManager.VERTICAL);
  3.         //给RrecyclerView设置布局管理者
  4.         mRrecyclerView.setLayoutManager(layoutManager);
  5.         //设置RrecyclerView适配器。
  6.         mRrecyclerView.setAdapter(new StaggeredGridAdapter(getApplication(),true));
  7.         //设置RrecyclerView背景颜色
  8.         mRrecyclerView.setBackgroundColor(Color.parseColor("#eeeeee"));
  9.         //设置RrecyclerView条目的动画
  10.         mRrecyclerView.setItemAnimator(new DefaultItemAnimator());
  11.         mRrecyclerView.addItemDecoration(new DividerGridItemDecoration(this));
复制代码


分割线:
       各位也看到,RecyclerView没有分割线啊,看起来好丑,对此,RecyclerView 提供了addItemDecoration(ItemDecoration decor)方法用来设置分割线但是ItemDecoration是抽象类,并且没有实现类,所以我们需要去自己定制分割线。首先我们要继承ItemDecoratio,在绘制的时候,去绘制decorator,即调用该类的
onDraw和onDrawOver方法,一般情况下只需要去复写其中一个就可以。
public void onDrawOver(Canvas c, RecyclerView parent) {}
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state){}
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent){}
ItemDecoration的实现类可以参考:DividerItemDecoration
添加分割线后的效果图:


RecyclerView条目点击事件:               
虽然说RecyclerView功能十分强大,但是RecyclerView并没有提供条目的点击事件,所以说要自己去设置点击事件。仿照ListView的setOnItemClickListener()方法,将被点击条目的View和position暴露给调用者。在Adapter的根布局中设置点击事件,之后在根布局被点击的时候进行接口回调,将被点击条目的View和position暴露出去,最后给Adapter设置点击事件,在根布局的点击事件的时候,就会回调Adapter的方法

首先声明一个接口对外暴露被点击条目的View和position
  1. public interface OnItemClickListener {
  2.         void onItemClick(View view, int position);
  3.     }
复制代码
在Adapter的根布局中设置点击事件
  1. public ListHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  2.    View view = LayoutInflater.from(mContext).inflate( R.layout.item_list, parent, false);
  3.                  view.setOnClickListener(this);
  4.             return new ListHolder(view) ;
  5.         }
复制代码
在onBindViewHolder()方法中获取position
  1. public void onBindViewHolder(ListHolder holder, int position) {
  2.         holder.setData(position);
  3.         holder.itemView.setTag(position);
  4.     }   
复制代码
提供设置条目监听的方法,并用成员变量mOnItemClickListener 进行接收
  1. public void setOnItemClickListener(OnItemClickListener listener) {
  2.             mOnItemClickListener = listener;
  3.         }
复制代码
实现根布局的点击事件点击事件
  1. @Override
  2.         public void onClick(View v) {
  3.             if(mOnItemClickListener != null) {
  4.                 mOnItemClickListener.onItemClick(v, (Integer) v.getTag());
  5.             }
  6.         }
复制代码
最后我们让Adapter去实现点击事件
  1. adapter.setOnItemClickListener(new OnItemClickListener() {
  2.             @Override
  3.             public void onItemClick(View view, int position) {
  4.                 Toast.makeText(DemoActivity.this, "position: "mList.get(position), Toast.LENGTH_SHORT).show();
  5.             }
  6.         });
复制代码
最后的效果图:

可以看到最后在点击条目李俊的时候弹出了相对应的信息,所以说咱们的这个思路去实现点击事件是没错的。


作者: chenzhiyuan    时间: 2019-1-25 14:52
可以现在吗?




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2