为什么嵌套权重不利于性能? 替代方案?

我已经编写了一些布局文件,其中使用了 layout_weight属性来创建不同视图之间的比例。

在某些时候,我开始收到关于嵌套重量的棉绒警告。

因此,我想知道为什么嵌套的权重对性能不利,如果有更有效的方法来创建视图尺寸之间的恒定比率,可以用于不同的屏幕大小,并且不需要通过几个布局文件指定大量的维度 dpi 值(我的意思是,对于不同的屏幕大小)。

谢谢!

87456 次浏览

我认为,唯一的选择是创建一个函数,它将被调用 onResume 并设置所有的大小和位置。无论如何,按重量你可以设置只有大小,但没有填充的(因此布局变得更加复杂) ,没有文本大小的(不可能以某种方式补偿这一点) ,更不用说像行数这样的东西。

嵌套权重不利于性能,因为:

布局权重需要对小部件进行两次测量 非零权重的 LinearLayout 嵌套在另一个中 线性布局与非零权重,然后测量的数量 呈指数增长。

最好使用 相对布局并根据其他视图的位置调整视图,而不使用特定的 dpi 值。

嵌套权重不好的主要原因是,当一个布局有带权重的子元素时,必须对其进行两次度量(我认为在 lint 警告中已经提到了这一点)。这意味着一个包含加权布局的加权布局必须测量四次,并且您添加的每个“层”的权重都以2的幂增加度量。

在 ICS (API 级别14)中增加了 GridLayout,它允许以前需要权重的许多布局的简单和“平面”解决方案。如果你正在开发早期版本的 Android,你会有一点困难的时间删除权重,但使用 RelativeLayout和平坦尽可能多的布局到驾驶室通常删除了很多嵌套的权重。

我认为(我可能会因此受到抨击) ,但我再次认为我的手机有一个四核处理器可以与大多数人的家用电脑相媲美(如果不是彻底摧毁的话)。

我也认为这种硬件能力是手机的未来。

所以我得出一个结论,只要你不被嵌套所迷惑(在 MHO 中一个布局不应该超过4层,如果你可能做错了) ,你的手机可能不会太在意重量。

有许多事情你可以做,将有一个更深远的影响性能,然后担心你的处理器做一些额外的数学。

(请注意,我有点幽默,所以不要把这篇文章看得太认真,除此之外,还有一些想法是你应该首先优化的,担心2-3级的深度体重对你的健康没有帮助)

更新: 正如我们所知,百分比支持库从 API 级别26被弃用。ConstraintLayout是实现相同的平面 xml 结构的新方法。

更新的 Github 项目

更新样本:

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">


<TextView
android:id="@+id/fifty_thirty"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffff8800"
android:gravity="center"
android:text="@string/fifty_fifty_text"
android:textColor="@android:color/white"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
android:textSize="25sp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />


<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ffff5566"
android:gravity="center"
android:text="@string/fifty_fifty_text"
android:textColor="@android:color/white"
android:textSize="25sp"
app:layout_constraintHeight_default="percent"
app:layout_constraintHeight_percent="0.5"
app:layout_constraintLeft_toRightOf="@id/fifty_thirty"
app:layout_constraintTop_toBottomOf="@id/fifty_thirty"
app:layout_constraintWidth_default="percent"
app:layout_constraintWidth_percent="0.5" />


</android.support.constraint.ConstraintLayout>

更新: 好消息 android 百分比支持库解决了我们的性能和嵌套混乱的加权 LinearLayout的问题

compile 'com.android.support:percent:23.0.0'

演示完毕

请考虑这个简单的布局来演示相同的内容。

percent support libray demo

<android.support.percent.PercentRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/fifty_huntv"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#ff7acfff"
android:text="20% - 50%"
android:textColor="@android:color/white"
app:layout_heightPercent="20%"
app:layout_widthPercent="50%" />
<TextView
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_toRightOf="@id/fifty_huntv"
android:background="#ffff5566"
android:text="80%-50%"
app:layout_heightPercent="80%"
app:layout_widthPercent="50%"
/>


</android.support.percent.PercentRelativeLayout>

避免性能降低嵌套 LinearLayout与重量。真的很棒! ! 。

有一个简单的解决办法可以避免嵌套的 LinearLayout 带有权重——只需要使用带磅和的 Tableayout 和带磅和的嵌套的 LinearLayout —— Tableayout 和 LinearLayout 有相同的属性(方向、磅和、布局 _ weight 等等) ,并且不显示消息——“嵌套的权重对性能不利”

例如:

 <TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="1">


<ImageView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.8"/>




<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.2"
android:orientation="horizontal"
android:weightSum="1">




<ImageView
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="0.4"/>


<TextView
android:layout_height="match_parent"
android:layout_width="0dp"
android:layout_weight="0.6"/>




</LinearLayout>


</TableLayout>