Android addViewInLayout使用解析

场景:之前原生项目开发中,遇到了动态2级表格需求,最开始使用viewGroup的addview()方法,动态对表格内容进行添加。但发现动态添加时,会导致渲染速度十分缓慢,在请求获取到数据后,过了好几秒才渲染完成。

分析:在查阅资料后,注意到了另一个view添加方法----addViewInLayout。该方法大致介绍为:在布局期间添加视图,如果你需要添加多个view,那么这个方法更加有用。如果index是负的,那将会放在最后一个。(大致就是这么个意思,人工翻译可能稍微有点偏差)

/**
     * Adds a view during layout. This is useful if in your onLayout() method,
     * you need to add more views (as does the list view for example).
     *
     * If index is negative, it means put it at the end of the list.
     *
     * @param child the view to add to the group
     * @param index the index at which the child must be added or -1 to add last
     * @param params the layout parameters to associate with the child
     * @param preventRequestLayout if true, calling this method will not trigger a
     *        layout request on child
     * @return true if the child was added, false otherwise
     */
    protected boolean addViewInLayout(View child, int index, LayoutParams params,
            boolean preventRequestLayout) {
        if (child == null) {
            throw new IllegalArgumentException("Cannot add a null child view to a ViewGroup");
        }
        child.mParent = null;
        addViewInner(child, index, params, preventRequestLayout);
        child.mPrivateFlags = (child.mPrivateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN;
        return true;
    }

具体使用:我这边定义了一个容器组件,作为二级表格的子组件,对外暴露setView方法,外层循环列表数据,循环调用setView方法进行子view的添加。其中,view参数对需要添加的子view,对应源码中的child参数;i对应源码中的index,一般i++自增就行。

/**
 * @author Flash
 * @date 2020-05-13 11:40
 * @description 用于添加View的LinearLayout,优化直接addView带来的绘制缓慢
 */
public class AddViewLinearLayout extends LinearLayout {
    public AddViewLinearLayout(Context context) {
        super(context);
    }

    public AddViewLinearLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public AddViewLinearLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params) {
        return super.addViewInLayout(child, index, params);
    }

    public void setView(View view, int i){
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        addViewInLayout(view, i, layoutParams);
    }
}

总结:在父组件(父类为ViewGroup的容器)有大量view添加操作时,推荐使用addViewInLayout替换addView,能明显提升渲染速度。对于addViewInLayout和addView的区别,addViewInLayout在所有子view添加完成后再计算与绘制;而addView在每次添加后均调用requestLayout()方法进行计算与绘制;具体可见ViewGroup中的源码。

(如有错误,请指正!)

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值