手写RecyclerView和RecylerView回收池-1

创建自定义RecylerView

  • 前言

我们的代码,为了节省大家的时间,大部分考虑复制、 粘贴的形式,代码在gitee都有,视频在B站有,如沐春风116

自定义RecylerView

  • 定义适配器
  public interface Adapter {

        /**
         * 创建ViewHolder的方法
         *
         * @param position
         * @param convertView
         * @param parent
         * @return
         */
        View onCreateViewHolder(int position, View convertView, ViewGroup parent);

        /**
         * 绑定ViewHolder的方法
         *
         * @param position
         * @param convertView
         * @param parent
         * @return
         */
        View onBinderViewHolder(int position, View convertView, ViewGroup parent);

        /**
         * 获取当前row item的控件类型
         *
         * @param row
         * @return
         */
        int getItemViewType(int row);

        /**
         * 获取当前控件类型的总数量
         *
         * @return
         */
        int getViewTypeCount();

        /**
         * 获取当前Item的总数量
         *
         * @return
         */
        int getCount();

        /**
         * 获取index Item的高度
         *
         * @return
         */
        int getHeight(int index);


    }
  • onMeasure方法
 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取RecylerView在当前布局的宽高
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        //当前内容的高度
        int h = 0;

        //判断适配器是否为空
        if (mAdapter != null) {
            //获取到当前数据中的总条数
            rowCount = mAdapter.getCount();
            //根据适配器的数据的总长度来创建数组
            heights = new int[rowCount];
            //循环获取到所有View的高度
            for (int x = 0; x < heights.length; x++) {
                heights[x] = mAdapter.getHeight(x);
            }
        }
        //获取所有数据的高度
        int tempHeight = sumArray(heights, 0, heights.length);
        //判断所有ItemView的高度和RecylerView的高度谁低
        h = Math.min(tempHeight, heightSize);
        setMeasuredDimension(widthSize, h);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    /**
     * 获取到数组中数据的高度
     *
     * @param heights 数组
     * @param index   从哪一个Item获取
     * @param count   一共要拿多少个Item高度
     * @return
     */
    private int sumArray(int[] heights, int index, int count) {
        int sum = 0;
        count = index + count;
        for (int x = index; x < count; x++) {
            sum += heights[x];
        }

        return sum;
    }
  • onLayout方法
 @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        //先判断是否需要布局,布局发生改变的时候重新调用
        if (needRelayout || changed) {
            needRelayout = false;
            //清除掉所有的View
            removeAllViews();
            //清除掉当前屏幕中显示的ItemView
            viewlist.clear();
            //如果适配器不为空,就去摆放itemView
            if (mAdapter != null) {
                //获取到RecylerView的宽高
                width = r - l;
                height = b - t;
                //定义布局ItemView的四个变量
                int top = 0, right, bottom, left = 0;
                for (int x = 0; x < rowCount; x++) {
                    //获取到绘制宽度的最右边
                    right = width;
                    bottom = top + heights[x];
                    //生成View
                    View view = makeAndStep(x, left, top, right, bottom);
                    //添加到当前ItemView的集合中
                    viewlist.add(view);
                    //因为循环摆放,所以 下一个控件的top就是上一个控件的bottom,而且需要累加
                    top=bottom;

                }

            }
        }

    }

我们本节课程,讲了RecylerView的测量和布局,下节课程我们将View的生成,再见,下节课继续。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容