自定义LayoutManager,仿微信朋友圈的九宫格效果

前言

之前在项目中我有写过自定义控件九宫格是根据ViewGroup写的,功能已经实现了,但是后来我感觉如果以后性能提升的话,可能在缓存这块有要求。所以,我感觉还是改变使用自定义LayoutManager来写这个控件,后期就直接使用RecyclerView本身的缓存机制来处理回收和重用的操作。

其实我们再自定义ViewGroup去编写我们的控件的时候,就有测量和布局。
在自定义LayoutManager中也有这些概念,但是还是有些区别,我们来看下。

重构和初始化

首先我们来给我们的自定义的LayoutManager取名为NineGridLayoutManager

public class NineGridLayoutManager extends RecyclerView.LayoutManager {
   
   
    private Pool<Rect> mCacheBorders;   //用于规定Item显示的区域

    public NineGridLayoutManager(Context context) {
   
   
	mCacheBorders = new Pool<>(new Pool.New<Rect>() {
   
   
            @Override
            public Rect get() {
   
   
                return new Rect();
            }
        });
    }

    @Override
    public RecyclerView.LayoutParams generateDefaultLayoutParams() {
   
   
        return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }
}

编写类的构造类,这里的Pool类是我自己写的一个缓存类,目的还是用于给我们后面的Grid的布局和测量存放参数。

public class Pool<T> {
   
   
    private SparseArrayCompat<T> mPool;
    private New<T> mNewInstance;

    public Pool(New<T> newInstance) {
   
   
        mPool = new SparseArrayCompat<>();
        mNewInstance = newInstance;
    }

    public T get(int key) {
   
   
        T res = mPool.get(key);
        if (res == null) {
   
   
            res = mNewInstance.get();
            mPool.put(key, res);
        }
        return res;
    }

    public interface New<T> {
   
   
        T get();
    }
}

代码不难, 核心思想就是建立一个索引,便于我们后期来获取这个类别。
我们来看一个generateDefaultLayoutParams()方法,这里是专门设置当前RecyclerView类的大小,可以看见,这里我们设置了WRAP_CONTENT,设置这个的目的就是等到子控件也就是我们的Grid测量完毕后,再来确定我们控件的大小。

测量

与ViewGroup的区别

首先,我们平时在自定义ViewGroup的时候,测量子View是在onMeasure方法中统一测量的;
而在自定义LayoutManager中,子View是当需要layout的时候才测量,LayoutManager已经提供了两个方法给我们直接调用了:

    measureChild(View child, int widthUsed, int heightUsed)
    measureChildWithMargins(View child, int widthUsed, int heightUsed)

这两个方法都可以测量子View,不同的是第二个方法会把Item设置的Margin也考虑进去,所以如果我们的LayoutManager需要支持Margin属性的话,就用第二个了。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值