ネストされた重みがパフォーマンスに悪いのはなぜですか?代替案?


160

layout_weight属性を使用して異なるビュー間の比率を作成するいくつかのレイアウトファイルを作成しました。

ある時点で、ネストされた重みに関するlint警告が出始めます。

したがって、ネストされた重みがパフォーマンスに悪いのはなぜか、および異なる画面サイズに使用でき、多くのディメンションdpi値を指定する必要がないビューディメンション間に一定の比率を作成するより効率的な方法があるかどうかと思います。いくつかのレイアウトファイル(異なる画面サイズの場合)を介して。

ありがとうございました!


2
レイアウト最適化のための素晴らしいポストdeveloper.android.com/training/improving-layouts/...
ムハンマドババール

回答:


140

ネストされた重みは、次の理由によりパフォーマンスに悪影響を及ぼします。

レイアウトの重み付けでは、ウィジェットを2回測定する必要があります。ゼロ以外の重みを持つLinearLayoutがゼロ以外の重みを持つ別のLinearLayout内にネストされると、測定値の数が指数関数的に増加します。

RelativeLayoutを使用し、特定のdpi値を使用せずに他のビューの場所に応じてビューを調整することをお勧めします。


87
知っておくと良いことは、メッセージの目的だと思います。含まれる指数が小さい場合、指数の影響はまだ小さいことに注意します。ネストの深さが浅い場合、これを実行するために必要なCPUを使用しないことは、一週間中甘やかして、日曜日の散歩だけに導く主力製品を持っているようなものです。それでも、ネストの深さが深い場合、それは十分に理解されたポイントです。
Carl

14
RelativeLayoutも、すべての子レイアウトを適切にレイアウトするために2回測定する必要があるため、レイアウトの重みを含むLinearLayoutをRelativeLayoutに変更してもパフォーマンスが向上しない場合があります。
Piasy 2015

相対レイアウトは常に機能するとは限りません。プロポーショナルウィジェットを作成する必要がある場合
アブドゥルフモン

67

更新:パーセントサポートライブラリは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'

デモはこちら

同じことを示すために、この単純なレイアウトを検討してください。

librayデモのサポート率

<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ウェイトでネストされたパフォーマンス低下ツールを回避しました。本当に素晴らしい!!!。


@danはい、重み付きのネストされた線形レイアウトがあることを考慮してください。
nitesh

3
「このクラスはAPIレベル26.0.0-beta1で廃止されました。代わりにConstraintLayoutおよび関連するレイアウトの使用を検討してください。」developer.android.com/reference/android/support/percent/...
saiyancoder

7
ConstraintLayoutは好きではありません。それは私にとって直感的に動作しません
カーソンホルツハイマー2017年

8
ConstraintLayoutは私にとって非常に難しい
BertKing 2017

1
おそらく、自動レイアウト制約についてのアップルの説明はより明確であり、ロジックも同じであるため、役立つ場合があります。残念ながら、droidのConstraintLayoutは、iOSの
AutoLayout

46

私はそう思う(おそらく私はこれに怒るだろう)が、私の電話には、ほとんどの人々の家庭用PCに匹敵する(完全に破壊しなければ)対抗できるクアッドコアプロセッサがあると思う。

また、この種のハードウェア機能は電話の未来だと思います。

だから私は結論に達しました、あなたがネスティングに夢中になっていない限り(MHOではレイアウトは4レベルを超えるべきではありません、そしてそれがあなたがおそらくそれを間違っているのであれば)、あなたの電話はあまり気にしないでしょうウェイトについて。

あなたができることはたくさんありますが、パフォーマンスにはるかに大きな影響を及ぼし、プロセッサーが余分な計算を行うことを心配します。

(私は少しユーモラスなので、この投稿からあまり真剣に受け取らないように注意してください。それ以外に、最初に最適化する必要があるものは他にもあるという考えと、2〜3レベルの深い重みについて心配することは役に立たないということですあなたの健康)


2
取得し、基本的に同意しますが、平均的なiphoneの使用量(Webサービス/その使用をサポートするサイトを含む)を、平均的な米国の家庭用冷蔵庫と同じくらいの年間エネルギー量と聞いています。したがって、このような環境への影響を考慮することは、開発者としての私たちの責任です。明らかにそれは常にバランスの取れた行動です:時間、コスト、パフォーマンス、安定性、そして一般的に私はあなたの見方に同意しますが、この種の影響も考慮する必要があると考えてください。もちろん、メンテナンス/拡張性もここにあります。とにかく-ポイントを作り、ありがとう。
MemeDeveloper 2015年

問題の具体的なポイントは、ウェブではなくデバイスでの処理に関するものであることに気づきますが、私のコメントは、OPの詳細よりも開発者としての優先順位についての一般的なポイントです。
MemeDeveloper 2015年

11

ネストされた重みが悪い主な理由は、レイアウトに重みを持つ子がある場合、2回測定する必要があるためです(これはlint-warningで言及されていると思います)。これは、加重レイアウトも含む加重レイアウトは4回測定する必要があり、追加する加重の各「レイヤー」は2の累乗でメジャーを増加させることを意味します。

ICS(APIレベル14)GridLayoutでは、これが追加されました。これにより、以前はウェイトが必要であった多くのレイアウトに対してシンプルで「フラットな」ソリューションが可能になります。以前のバージョンのAndroid向けに開発している場合は、ウェイトを削除するのが少し難しくなりRelativeLayoutますが、レイアウトをできるだけキャブにフラット化して使用すると、通常、ネストされたウェイトの多くが削除されます。


9
GridLayout またはで 同じ結果が得られるとは思いませんRelativeLayout。例GridLayout:「GridLayoutは、ウェイトで定義されているウェイトの原則をサポートしていません。したがって、一般に、GridLayoutを構成して、複数のコンポーネント間に余分なスペースを分散させることはできません。」
Timmmm 2012年

API 21から、ウェイトの概念がGridLayoutに追加されました。古いAndroidデバイスをサポートするには、v7サポートライブラリのGridLayoutを使用できます。android.support.v7.widget.GridLayout
ЭвансгелистEvansgelist

2

重み付きの入れ子になったLinearLayoutsを回避する簡単な解決策があります-weighSumでTablelayoutを使用し、weightSumで入れ子になったLinearLayoutを使用します-TablelayoutはLinearLayout(orientation、weightSum、layout_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>

1

唯一の選択肢は、onResumeと呼ばれ、すべてのサイズと位置を設定する関数を作成することです。とにかく、重みによって、サイズのみを設定できますが、パディング(レイアウトはさらに複雑になります)、textSize(これをどうにかして補正することは不可能)、行数などは設定できません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.