安卓性能优化之懒加载(View的懒加载)

时间:2024-03-28 22:01:11

1、背景:为什么需要View的懒加载。      

    我们在做安卓项目的时候,经常会有一个使用场景:需要在运行时根据数据动态决定显示或隐藏某个View和布局。  

    上述场景,我们通常的解决方案就是:就是把可能用到的View先写在布局里,再初始化其可见性都设为View.GONE,然后在代码中根据数据动态的更改它的可见性。  

    虽然这样的实现,逻辑简单而且控制起来比较灵活;但是也存在一定的缺点耗费资源。

    因为即使把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,故而:

    (1)仍然会创建对象;

    (2)仍然会被实例化;

    (3)仍然会被设置属性从而导致耗费内存等资源。        

    这时候,我们就需要View的懒加载。        

 

2、什么是ViewStub。  

    (1)ViewStub一个是直接继承于View的类。

    (2)实质上是一个宽高都为 0 的不可见 View。        

 

3、为什么能用ViewStub实现View的懒加载

    ViewStub的特性: 

    (1)在初始化布局文件时,程序无需初始化<ViewStub>标签所指向的布局文件。 只有在特定的条件下,所指向的布局文件才需要被渲染,且此布局文件直接将当前的 <ViewStub> 替换掉。但这里的替换并不是完全意义上的替换,布局文件的 layout params 是以 ViewStub 为优先。

    (2)当初次渲染布局文件时,ViewStub 控件虽然也占据内存, 但是相比于其他控件, 它所占内存很小. 它主要是作为一个“占位符”, 放置于 View Tree中, 且它本身是不可见的。  

    由于具有以上特性,只有当一个ViewStub的inflate()方法被调用或者被设为View.VISIBILITY时,此时ViewStub会把设定的布局才会被创建对应的对象和实例化,并替换当前ViewStub的位置,显示相应的效果。虽然一开始ViewStub就存在于视图树中,但是直到setVisibility(int)或inflate()方法被调用时才消耗资源,否则是不加载控件的,因此消耗的资源小。故而, ViewStub可以实现View的懒加载。  

 

4、实现方法  

(1)关键点      

    <ViewStub>标签可以看成是一个“占位符“,可以看成自身是不呈现任何UI效果的视图容器,主要就是用于存放真实的布局和视图,所以除了设置必要的尺寸属性和位置之外,通常必须设置三个重要属性和一个回调监听接口:

        <1>android:id

                ——ViewStub 自身的Id,无论是否被inflate,都可以通过findViewById拿到对应的ViewStub控件本身。  

        <2>android:inflatedId

                ——ViewStub设置的被映射的布局文件中的跟节点的Id,inflate之后可以通过findViewById获取到对应的被映射的布局对象。  

        <3>android:layout

                ——将要映射的布局文件名

        <4>ViewStub.OnInflateListener

                ——当ViewStub成功映射预先设置的布局会触发回调  

(2)使用方法      

    设置完上述关键点,在程序中调用 inflate() 方法就能加载对应的layout。  

    还可以设定 Visibility 为 VISIBLE 或 INVISIBLE,也会触发 inflate()。 但是这里只会在首次使用 setVisibility() 会加载要渲染的布局文件。再次使用只是单纯的设置可见性。  

    对 inflate() 操作也只能进行一次,因为 inflate() 的时候是其指向的布局文件替换掉当前 <ViewStub> 标签。之后, 原来的布局文件中就没有 <ViewStub> 标签了。因此,如果多次 inflate() 操作,会报错:ViewStub must have a non-null ViewGroup viewParent。  

(3)demo  

        <1>建立将要被映射的布局

安卓性能优化之懒加载(View的懒加载)
建立将要被映射的布局​​​​​

 

        <2>建立主布局引入ViewStub

安卓性能优化之懒加载(View的懒加载)
建立主布局引入ViewStub

 

        <3>实现MainActivity

安卓性能优化之懒加载(View的懒加载)
实现MainActivity