性能优化系列(二)布局优化

三种标签

include、ViewStub、merge

include标签:常用于将布局中的公共部分提取出来供其他layout共用。

ViewStub控件:可以用来引入一个外部布局,不同的是,viewstub引入的布局默认不显示,不会扩张,即既不会占用显示也不会占用位置,从而在解析layout时节省cpu和内存。例如:显示网络连接失败的时候的error布局(默认不显示,只有网络不好才显示)。

merge标签:include后可能导致布局嵌套过多,多余不必要的layout节点,从而导致解析变慢,不必要的节点和嵌套。他就是为了解决include多层嵌套而存在的。

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".display1.Kotlin27"
    tools:ignore="MissingConstraints"
    android:orientation="vertical">

    <include layout="@layout/performance_contentview_1"/>

    <ViewStub
        android:id="@+id/viewStub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout="@layout/performance_contentview_2"
        />

    <include layout="@layout/performance_contentview_3"/>
</LinearLayout>

代码:

class Kotlin27 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin27)
        //布局优化
        /**
         * ViewSub默认为gone
         * 这里用代码显示
         */
        val viewStub = findViewById<ViewStub>(R.id.viewStub)
        viewStub.inflate()

        /**
         * 查看View层级
         */
        //include
        val tv1 = findViewById<TextView>(R.id.includeViewChild)
        Log.e("Kotlin27",("zjw-include: View-layerCount = ")+getViewLayer(tv1))
        //viewStub
        val tv2 = findViewById<TextView>(R.id.viewStubViewChild)
        Log.e("Kotlin27",("zjw-viewStub: View-layerCount = ")+getViewLayer(tv2))
        //merge
        val tv3 = findViewById<TextView>(R.id.mergeViewChild)
        Log.e("Kotlin27",("zjw-merge: View-layerCount = ")+getViewLayer(tv3))
    }

    private fun getViewLayer(view: View):Int{
        if (view.parent==null){
            return 0
        }else{
            Log.e("Kotlin27",view.parent.javaClass.name)
            return getViewLayer(view.parent as View) + 1
        }
    }
}

打印层级:

E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: androidx.constraintlayout.widget.ConstraintL
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: androidx.appcompat.widget.ContentFrameLayout
E/Kotlin27: androidx.appcompat.widget.FitWindowsLinearLa
E/Kotlin27: android.widget.FrameLayout
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: com.android.internal.policy.DecorView
E/Kotlin27: zjw-include: View-layerCount = 8
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: androidx.constraintlayout.widget.ConstraintL
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: androidx.appcompat.widget.ContentFrameLayout
E/Kotlin27: androidx.appcompat.widget.FitWindowsLinearLa
E/Kotlin27: android.widget.FrameLayout
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: com.android.internal.policy.DecorView
E/Kotlin27: zjw-viewStub: View-layerCount = 8
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: androidx.appcompat.widget.ContentFrameLayout
E/Kotlin27: androidx.appcompat.widget.FitWindowsLinearLa
E/Kotlin27: android.widget.FrameLayout
E/Kotlin27: android.widget.LinearLayout
E/Kotlin27: com.android.internal.policy.DecorView
E/Kotlin27: zjw-merge: View-layerCount = 7

子布局:

1、performance_contentview_1

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingConstraints">

    <LinearLayout
        android:id="@+id/contentLL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/includeViewChild"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contentView1-child1" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contentView1-child2" />
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingHorizontal="5dp"
        android:paddingVertical="10dp"
        android:text="contentView1-noChild"
        app:layout_constraintTop_toBottomOf="@id/contentLL" />
</androidx.constraintlayout.widget.ConstraintLayout>

2、performance_contentview_2

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:ignore="MissingConstraints">

    <LinearLayout
        android:id="@+id/contentLL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/viewStubViewChild"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contextView2-child1" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contextView2-child2" />
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingHorizontal="5dp"
        android:paddingVertical="10dp"
        android:text="contextView2-noChild"
        app:layout_constraintTop_toBottomOf="@id/contentLL" />
</androidx.constraintlayout.widget.ConstraintLayout>

3、performance_contentview_3

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingConstraints">

    <LinearLayout
        android:id="@+id/contentLL"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:id="@+id/mergeViewChild"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contentView3-child1" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:paddingHorizontal="5dp"
            android:paddingVertical="10dp"
            android:text="contentView3-child2" />
    </LinearLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:paddingHorizontal="5dp"
        android:paddingVertical="10dp"
        android:text="contentView3-noChild"
        app:layout_constraintTop_toBottomOf="@id/contentLL" />
</merge>

结果打印:include、ViewStub都是8层,merge为7层。

android.widget.LinearLayout
androidx.constraintlayout.widget.ConstraintLayout
android.widget.LinearLayout
androidx.appcompat.widget.ContentFrameLayout
androidx.appcompat.widget.ActionBarOverlayLayout
android.widget.FrameLayout
android.widget.LinearLayout
com.android.internal.policy.impl.PhoneWindow$DecorView
zjw-include: View-layerCount = 8

android.widget.LinearLayout
androidx.constraintlayout.widget.ConstraintLayout
android.widget.LinearLayout
androidx.appcompat.widget.ContentFrameLayout
androidx.appcompat.widget.ActionBarOverlayLayout
android.widget.FrameLayout
android.widget.LinearLayout
com.android.internal.policy.impl.PhoneWindow$DecorView
zjw-viewStub: View-layerCount = 8

android.widget.LinearLayout
android.widget.LinearLayout
androidx.appcompat.widget.ContentFrameLayout
androidx.appcompat.widget.ActionBarOverlayLayout
android.widget.FrameLayout
android.widget.LinearLayout
com.android.internal.policy.impl.PhoneWindow$DecorView
zjw-merge: View-layerCount = 7

分析:

android.widget.LinearLayout
androidx.constraintlayout.widget.ConstraintLayout
android.widget.LinearLayout
androidx.appcompat.widget.ContentFrameLayout
androidx.appcompat.widget.FitWindowsLinearLayout == ActionBarOverlayLayout(toolbar)
android.widget.FrameLayout
android.widget.LinearLayout
com.android.internal.policy.DecorView

设置主题有ActionBar的时候打印ActionBarOverlayLayout,否则打印FitWindowsLinearLayout。

5.1手机模拟器跑一下:与10.0版本保持一致。

E/Kotlin27: android.widget.LinearLayoutRect(0, 284 - 1440, 420)
E/Kotlin27: androidx.constraintlayout.widget.ConstraintLayoutRect(0, 284 - 1440, 556)
E/Kotlin27: android.widget.LinearLayoutRect(0, 284 - 1440, 762)
E/Kotlin27: androidx.appcompat.widget.ContentFrameLayoutRect(0, 284 - 1440, 2392)
E/Kotlin27: androidx.appcompat.widget.ActionBarOverlayLayoutRect(0, 284 - 1440, 2392)
E/Kotlin27: android.widget.FrameLayoutRect(0, 88 - 1440, 2392)
E/Kotlin27: android.widget.LinearLayoutRect(0, 88 - 1440, 2392)
E/Kotlin27: com.android.internal.policy.impl.PhoneWindow$DecorViewRect(0, 0 - 1440, 2392)
E/Kotlin27: zjw-include: View-layerCount = 8

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 在app开发中布局几乎是必不可少的基础,随着UI越来越多,布局的重复性、复杂度也会随之增长。而每一个view都需要...
    初夏的雪阅读 1,209评论 0 11
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,957评论 2 45
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    wgl0419阅读 6,666评论 1 9
  • 一、初识布局优化 通过《Android性能优化(一)之启动加速35%》我们获得了闪电般的App启动速度,那么在应用...
    未来的理想阅读 10,015评论 16 51
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 131,330评论 2 7

友情链接更多精彩内容