Why are nested weights bad for performance? Alternatives?

后端 未结 6 1460
深忆病人
深忆病人 2020-11-22 16:26

I have written a couple layout files where I used the layout_weight attribute to create a ratio between different views.

At some point, I start getting

相关标签:
6条回答
  • 2020-11-22 16:50

    I think, the only alternative is to make a function that would be called onResume and will set all sizes and positions. Anyway, by weight you can set only sizes but no padding's (so layouts become even more complicated), no textSize's (impossible to compensate this somehow), let alone such things as number of lines.

    0 讨论(0)
  • 2020-11-22 16:51

    There is an easy solution to avoid nested LinearLayouts with weights - just use Tablelayout with weighSum and nested LinearLayout with weightSum - Tablelayout has the same attributes as LinearLayout(orientation, weightSum, layout_weight, etc.) and doesn't show message - "nested weights have bad for performance"

    Example:

     <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>
    
    0 讨论(0)
  • 2020-11-22 16:57

    Update: As we know the percent support library is deprecated from API level 26. ConstraintLayout is the new way to achieve the same flat xml structure.

    Updated Github Project

    Updated Samples:

    <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>
    

    Update: Great news android percent support library solves our problem of performance and nested messy weighted LinearLayout

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

    Demo HERE

    Consider this simple layout to demonstrate the same.

    <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>
    

    Avoided performance degrader nested LinearLayout with weights.Really awesome!!!.

    0 讨论(0)
  • 2020-11-22 16:58

    The main reason why nested weights are bad is that when a layout has children with a weight, it has to be measured twice (I think this is mentioned in the lint-warning). This means that a weighted layout that also contains a weighted layout has to measured four times, and each 'layer' of weights you add increase the measures with a power of two.

    In ICS (API level 14) the GridLayout was added, which allows simple and 'flat' solutions for many layouts which previously required weights. If you are developing for earlier versions of Android you will have a slightly harder time removing weights, but using a RelativeLayout and flattening as much as possible of your layout into that cab usually remove a lot of the nested weights.

    0 讨论(0)
  • 2020-11-22 17:07

    I think (and I will probably be flamed for this), but again I think my phone has a quad core processor to rival (if not utterly destroy) most peoples home PC's.

    I also think this kind of hardware capability is the future of phones.

    So I come to a conclusion, that as long as you are not getting carried away with nesting (in MHO a layout should never be more then 4 levels deep, and if it is you are probably doing it wrong), your phone could care less about having weights.

    There are many things you can do that will have a much more far reaching effect on performance, then worrying about your processor doing some extra math.

    (please note that I am being slightly humorous, and so not to take anything too seriously from this post, other then the idea that there are other things you should optimize first, and that worrying about a 2-3 level deep weight is not helping your health)

    0 讨论(0)
  • 2020-11-22 17:08

    Nested weights are bad for performance because:

    Layout weights require a widget to be measured twice. When a LinearLayout with non-zero weights is nested inside another LinearLayout with non-zero weights, then the number of measurements increase exponentially.

    It's better to use RelativeLayouts and adjust your view according to the places of other views without using specific dpi values.

    0 讨论(0)
提交回复
热议问题