Android的UI优化之merge、include、ViewStub标签

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GerryRun/article/details/82665207

最近要对新接手的一个Android项目做性能优化,经过大量的查阅学习,总结了一些知识点,特此记录。此篇记录UI性能方面的优化思路。


说起UI的优化,不得不了解一下过度绘制的概念、产生原因和表现、查看以及优化overdraw的方法。
1. 过度绘制(Overdraw)概念
是指在一帧的时间(16.67ms)内,像素被多次绘制
2. 产生的原因和表现
一个像素被绘制一次是最理想的状态,但是实际情况中,由于重叠的布局导致一些像素被多次绘制,每次绘制都是CPU的一组绘图命令和GPU的一些操作,在单次绘制的时长超过16ms时,便会出现掉帧现象,也就是卡顿。
3. 如何查看
Android系统是为我们提供了测量overdraw的功能的,打开步骤:开发者选项=>调试GPU过度绘制(show GPU overdraw),打开之后便可以查看目标页面的overdraw状态了。打开了之后系统提供了四种不同的颜色来绘制屏幕,用来指示overdraw的位置和程度:①没有颜色:没有发生overdraw,像素只被绘制一次。②蓝色:区域像素被绘制两次。如果大片的蓝色是可以接受的,如果整个屏幕都是蓝色,便可以在布局的时候减少一层。③绿色:区域像素被绘制三次,如果出现绿色,虽然可以接受,但是也需要着手优化和减少。④浅红:区域像素被绘制4次,小范围可以接受。⑤暗红:区域像素被绘制5次。当像素被绘制5次及以上,就是错误的,尽快修复。
4. 优化overdraw的方法
优化overdraw的原则是尽量避免重复对不可见元素的绘制和尽量减少布局层级。这个时候merge、ViewStub标签便能派上用场了。


ViewStub

ViewStub:即高效占位符。
应用场景:在前端开发中,经常是需要根据条件动态显示或隐藏某个view或layout,常用的做法是先对目标View或者layout的可见属性设置成View.GONE,就可以简单灵活地控制显示或者隐藏。但是,这样会浪费资源,因为虽然View或者layout可见性是GONE,但是在inflate布局的时候,目标View或layout依然会被inflate,进而创建对象、被实例化、设置属性值。
这个时候,可以使用ViewStub标签。ViewStub是一个轻量级的View,它一个看不见的,不占布局位置,占用资源非常小的控件。使用时为ViewStub指定布局,在页面inflate时,
只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub所向的布局才会被Inflate和实例化。使用代码示例:

布局文件:


        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <Button
                    android:id="@+id/bt_show"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="显示ViewStub" />

                <Button
                    android:id="@+id/bt_change"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="更改ViewStub" />

                <Button
                    android:id="@+id/bt_hide"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="隐藏ViewStub" />

            </LinearLayout>

            <!--通过ViewStub的自身id,找到控件并调用 ViewStub#inflate()之后就失效
                inflatedId是在ViewStab#inflate()之后替换的View 的id
                layout是用来替换ViewStub的布局-->
            <ViewStub
                android:id="@+id/view_stub_test"
                android:inflatedId="@+id/rl_item"
                android:layout="@layout/layout_item_list_database_prac"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

        </LinearLayout>

activity中使用代码,贴出按钮的点击事件代码:

switch (v.getId()) {
                case R.id.bt_show:
                    /****
                     * ViewStub 只能调用inflate()一次,
                     * 调用之后,会被从视图树中移除,所以进行判空
                     */
                    if (findViewById(R.id.view_stub_test) != null)
                        ((ViewStub) findViewById(R.id.view_stub_test)).inflate();
                    else {
                        /**
                         * ViewStub为空就是已经被加载,用ViewStub的inflatedId属性查找替换布局
                         */
                        findViewById(R.id.rl_item).setVisibility(View.VISIBLE);
                    }
                    break;
                case R.id.bt_change:
                    if (!findViewById(R.id.rl_item).isShown()) {
                        return;
                    }
                    i = ++i;
                    ((TextView) findViewById(R.id.text_layout_item_data_base_recycler)).setText("change" + (i));
                    break;
                case R.id.bt_hide:
                    if (findViewById(R.id.rl_item) == null)
                        return;
                    findViewById(R.id.rl_item).setVisibility(View.GONE);
                    break;
            }

首次显示页面:

这里写图片描述

点击 显示ViewStub Button:

这里写图片描述

点击 更改ViewStub Button:

这里写图片描述

点击 隐藏ViewStub Button:

这里写图片描述



至此,ViewStub标签的使用介绍完毕,下面介绍merge标签的使用:

猜你喜欢

转载自blog.csdn.net/GerryRun/article/details/82665207