ConstraintLayout真的就那么强?拉出来比一比!

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第8天,点击查看活动详情

ConstraintLayout 性能对比与分析

关于 ConstraintLayout 的介绍就不用多说了吧,到今天来说已经是基本控件了,如果真有不会用的看官网介绍。

现在感觉大家都已经有点神话 ConstraintLayout 了,现在创建 Activity 的 xml 。默认的根布局就是 ConstraintLayout 了,咋滴,真要我们把全部页面都用一个 ConstraintLayout 包裹吗?

百度搜索一下 ConstraintLayout 。全是优化布局!!!

我心里打个问号?真有这么强?ConstraintLayout 就无敌了?

这里我用 LinearLayout RelativeLayout ConstraintLayout 做一个对比,实现同样的效果,三种布局分别来实现,看看耗时多少!

耗时方法统计为 设置布局之前与展示布局之后。

    override fun onCreate(savedInstanceState: Bundle?) {
        start = System.currentTimeMillis()

        super.onCreate(savedInstanceState)
    }

    override fun onResume() {
        super.onResume()
        end = System.currentTimeMillis()

        YYLogUtils.w("耗时:" + (end - start))
    }
复制代码

一、简单布局测试

实现一个简单的2行文本

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="@dimen/d_15dp"
    android:paddingBottom="@dimen/d_15dp"
    tools:background="@color/white">


    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="君不见," />


    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="黄河之水天上来" />


    <TextView
        android:id="@+id/tv_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="奔流到海不复回" />


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_1"
        android:layout_marginTop="@dimen/d_10dp"
        android:text="君不见" />


    <TextView
        android:layout_below="@id/tv_1"
        android:layout_marginTop="@dimen/d_10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="高堂明镜悲白发" />


    <TextView
        android:layout_below="@id/tv_1"
        android:layout_marginTop="@dimen/d_10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="朝如青丝暮成雪" />

</RelativeLayout>
复制代码
<?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"
    android:paddingTop="@dimen/d_15dp"
    android:paddingBottom="@dimen/d_15dp"
    tools:background="@color/white">

    <TextView
        android:id="@+id/tv_1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="君不见,"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tv_2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:text="黄河之水天上来"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tv_3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="奔流到海不复回"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


    <TextView
        android:id="@+id/tv_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="@dimen/d_10dp"
        android:layout_weight="1"
        android:text="君不见,"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_1" />


    <TextView
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="@id/tv_4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:text="高堂明镜悲白发" />


    <TextView
        app:layout_constraintTop_toTopOf="@id/tv_4"
        app:layout_constraintRight_toRightOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="right"
        android:text="朝如青丝暮成雪" />

</androidx.constraintlayout.widget.ConstraintLayout>
复制代码

结果:

LinearLayout RelativeLayout ConstraintLayout
53 53 61
57 54 54
52 53 54
51 52 59
52 62 53
53 59 53

结果是简单布局实现 LinearLayout 更优秀。RelativeLayout 和 ConstraintLayout 的 区别不大。

二、稍微复杂布局测试

实现的效果如下:

这里我们就不贴重复的代码了,实现的方式与上面类似。同样的效果只是多添加几层,看看实现的结果。

LinearLayout RelativeLayout ConstraintLayout
83 83 85
85 81 87
86 84 93
83 83 85
99 81 84
86 82 86

稍微复杂的布局中,,确实 RelativeLayout 和 ConstraintLayout 这种布局实现减少层级之后确实展示的更快了。LinearLayout 已经没有优势了!但是这里 RelativeLayout 的要比 ConstraintLayout 强一点!

话不多说,我们看看比较复杂的布局测试。

三、比较复杂布局测试

实现效果如下:

一共14行布局,我们就不贴重复的代码了,实现的方式与上面类似。都是很基本的实现方式了,我们直接看看结果。

LinearLayout RelativeLayout ConstraintLayout
140 162 156
140 144 163
150 155 165
142 144 159
140 147 152
153 150 161

可以看到在比较复杂的布局中,LinearLayout 又赶超上来了,这里 RelativeLayout 与 ConstraintLayout 的性能差不多了。

可以看到在比较复杂的布局中还是不太推荐 全部一个 ConstraintLayout 包裹实现。

四、RV列表中的使用

这是静态布局的展示,那么在列表中的使用性能又如何呢?

这里直接上图吧!

ConstraintLayout 的Item布局实现,明显卡顿,都已经超出屏幕外了。后续往回拉动展示缓存布局的时候也会超出16.6ms。 会出现轻微的卡顿。

LinearLayout 的情况与 RelativeLayout 的布局类似,虽然也卡,但是没有那么的明显。后续往回拉动展示缓存布局的时候也明显帧数更低。不会出现卡顿。

为什么出现这种情况。我们看看相同的布局 他们 onMeasure onLayout onDraw的耗时。(注:这里的耗时是纳秒)

Cons01 onMeasure - 27323438
Cons01 onMeasure - 22129271
Cons01 onLayout - 3678230
Cons01 onDraw - 5311458

Rel01 onMeasure - 8344687
Rel01 onMeasure - 1069531
Rel01 onLayout - 2910156
Rel01 onDraw - 4294010

Lin01 onMeasure - 3184948
Lin01 onMeasure - 3351094
Lin01 onLayout - 5469532
Lin01 onDraw - 5566250

每一个布局的展示都是两次onMeasure 一次onLayout 一次onDraw。这都是正常的,因为ViewGroup要先测量子布局再测量自己。

重点是看 ConstraintLayout 的测量耗时,这也太那啥了,ConstraintLayout 测量的耗时为 LinearLayout 的8倍。

五、总结

当前使用的 ConstraintLayout 测试版本为2.0.3 非最新版本,测试机型为7.0老款机型,本人非专业测试,测试工具也不专业,当前测试结果仅供参考。

尽管如此,我们还是可以得到大致的结论。

ConstraintLayout 并没有比 RelativeLayout性能好到哪里去。在简单的布局和复杂的布局中 LinearLayout 还是YYDS。 在稍微复杂的布局中,我们确实可以通过减少层级优化布局加载数据,此时使用 ConstraintLayout 确实不错。

在复杂的布局中我们可以使用 LinearLayout 作为根视图,内部的每一个稍微复杂的布局View,我们可以用 ConstraintLayout 布局,做到 LinearLayout + ConstraintLayout 的布局方式,这才是最优解(吧?)

在列表中尽量避免使用 ConstraintLayout 做Item的整个根视图,测量会比较耗时。推荐使用 LinearLayout ,或者 LinearLayout + ConstraintLayout 的布局方式。

话虽如此,但是 ConstraintLayout 的一些新特效确实太香,比如百分比布局,宽高比例布局适配太方便,比如 ConstraintLayout 中的 MotionLayout 做动画也太方便了趴。

所以,布局的应用就这样了。有了自己的思考,就知道如何组合的使用 ViewGroup 布局,如果真的全部使用 ConstraintLayout 来布局,那不得卡到爆。

OK,说了这么多,如果大家有不同意见,欢迎到评论区留言哦。

到处完结。

猜你喜欢

转载自juejin.im/post/7110404818627198989
今日推荐