RecylerView详解

实现功能

官方定义:A flexible view for providing a limited window into a large data set。简单来说就是一种可以通过灵活的视图形式展示大量数据的列表组件

设计哲学

我其实也并不知道该组件的设计思路是什么,所以是比较主观的

适配器

该组件需要用户提供相对规整的数据,以及数据对应的自定义的视图,用一个map去存储?不行的,有一个原因是自定义视图中的子view对应的数据也需要用户去决定,所以需要设计一个适配器来处理这样杂乱无章的数据与视图(整流),将通过适配器处理后的数据对象交给组件。

布局管理器

这么多视图,哪个视图放到哪也是一个问题?这就需要布局管理器,其需要整合目前市面是流行的布局且具有可扩展性,所以会设计出一个布局管理器

简单使用
List<String> mDatas = getDatas()
mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
//设置布局管理器
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
// 设置适配器
mRecyclerView.setAdapter(new HomeAdapter(mDatas))

// adapter
 class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder>
    {
   
         private List<String> mDatas;
         
         HomeAdpater(List<String> datas) {
   
             this.mDatas = datas;
         }
        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
        {
   
            MyViewHolder holder = new MyViewHolder(LayoutInflater.from(
                    HomeActivity.this).inflate(R.layout.item_home, parent,
                    false));
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position)
        {
   
            holder.tv.setText(mDatas.get(position));
        }

        @Override
        public int getItemCount()
        {
   
            return mDatas.size();
        }
        // Viewhodler类
        class MyViewHolder extends ViewHolder
        {
   

            TextView tv;

            public MyViewHolder(View view)
            {
   
                super(view);
                tv = (TextView) view.findViewById(R.id.id_num);
            }
        }
    }
源码分析
主体初始化
构造器

构造器的代码是在findViewById触发,其主要是初始化了三个类分别是ChildHelper,AdapterHelper,LayoutManagerChildHelper是管理recylerview的孩子节点的。AdapterHelper官方解释是管理adapter的更新的类。最后一个前面提到了是管理布局形式的类

测量(onMeasure)
// 关键源码
 protected void onMeasure(int widthSpec, int heightSpec) { 
    if (mLayout.isAutoMeasureEnabled()) { 
        ...
        if (mState.mLayoutStep == State.STEP_START) {
            dispatchLayoutStep1();
        }
        mLayout.setMeasureSpecs(widthSpec, heightSpec);
        mState.mIsMeasuring = true;
        dispatchLayoutStep2();
        // now we can get the width and height from the children.
        mLayout.setMeasuredDimensionFromChildren(widthSpec, heightSpec);    
        ...
      }
 }

由于系统自带的几个布局管理器默认设置了自动测量参数mAutoMeasure=ture,所以测量主要分两步,其中dispatchLayoutStep1,dispatchLayoutStep2。
在这里插入图片描述

  • dispatchLayoutStep1

主要工作就是记录一些view的状态和初始化动画相关的类其中调用了addToPreLayout去存储当前view的状态

  • dispatchLayoutStep2

这一步工作比较关键,用于测量+布局,全权交由布局管理器处理,这里我们以线性布局管理器举例,入口函数为onLayoutChinlder

public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {    
    ...
    // 寻找锚点,即确定布局的起始点
    if (!mAnchorInfo.mValid || mPendingScrollPosition != NO_POSITION
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值