Android使用ViewStub实现布局优化方法示例

实践过程

Hello,大家好啊,我是小空,今天带大家了解下动态加载控件ViewStub。

在平时开发中经常会遇到复杂布局,而每一个view都是会占据内存和消耗cpu的(即使再小,累计成多,一般嵌套7级以上就有明显的卡顿了),布局优化就是我们常做的任务之一,甚至是一块心病。所以我们工作中就要留意布局优化的手段,ViewStub就是其中之一。

大家应该听过merge标签,将某个布局文件的根布局写成merge的,然后对应的布局include引用,会默认不会引入merge帮我们减少一层嵌套。而ViewStub也是类似的实现,区别在于include的merge就已经在view的树结构中了,而viewstub默认没在树中,只有代码调用初始化的时候才会进入树中。

就好比我们排队,前者是两人同时排队,后者是一个人排队拿着个占位的牌子帮另一人占位,等合适的时机再将另一个人插入进来,牌子拿开。

实现方式



 
    

布局中ViewStub其实就是个宽高全是0的View,它默认是不可见的(不是GONE或INVISIBLE的不可见,而是根本没在view的树结构里),然后通过调用setVisibility函数或者Inflate函数会将我们的目标布局给加载出来,这样就实现了延迟加载的效果。

idBtnInflate.setOnClickListener{
    viewStubName. inflate()
    //或者是下面的形式加载,因为里面会执行inflate
    // viewStubName.visibility=View.VISIBLE
}

知识点

注意,viewstub执行inflate函数后,在当前页面activity未销毁之前无法进行第二次inflate。

为什么第二次inflate的时候会报错呢?仔细看上面列举的排队比喻,viewstud就是占位的那个牌子,当你引入的layout插进去后就会移除viewstub控件。那么下次你再进行inflate的时候自然就是报错了。

为什么大小为0且不绘制? 我们找到ViewStub的源码:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    setMeasuredDimension(0, 0);
}
@Override
public void draw(Canvas canvas) {
}
@Override
protected void dispatchDraw(Canvas canvas) {
}
public void setWillNotDraw(boolean willNotDraw) {
    setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
}

重写draw和dispatchDraw,但却什么也不写,再接着onMeasure中进行setMeasuredDimension(0,0);就实现了宽高为0.

而不绘制是将view的Flags设置为了WILL_NOT_DRAW,这个值的作用是view不会进行onDraw方法。

顺便一提:在当下设备性能越来越好的背景下,关于优化的事情放在开发周期后面再说吧。先出产品再迭代。随着经验的积累,正常开发你也会留意性能优化,随手就解决了。

以上就是Android使用ViewStub实现布局优化方法示例的详细内容,更多关于Android ViewStub布局优化的资料请关注脚本之家其它相关文章!

你可能感兴趣的:(Android使用ViewStub实现布局优化方法示例)