android:android:weightSumとは何ですか?どのように機能しますか?


回答:


132

ドキュメントごとにandroid:weightSum、最大重量合計を定義し、layout_weight明示的に指定されていない場合はすべての子の合計として計算されます。

LinearLayout水平方向に3 ImageViewsを持ち、中に3がある例を考えてみましょう。今、私たちはこれらがImageViews常に等しいスペースを取ることを望んでいます。これを達成するためにlayout_weight、それぞれのImageViewを1に設定するとweightSum、コメントに示されているようにが3に等しくなるように計算されます。

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    <!-- android:weightSum="3" -->
    android:orientation="horizontal"
    android:layout_gravity="center">

   <ImageView
       android:layout_height="wrap_content"       
       android:layout_weight="1"
       android:layout_width="0dp"/>
  .....

weightSum レイアウトを任意のデバイスで正しくレンダリングするのに役立ちます。これは、幅と高さを直接設定した場合には起こりません。


145
これはの目的の説明ではありませんweightSum。あなたの例の振る舞いはweightSum省略されたものと同じであり、実際にはそのシナリオではweightSumを指定すべきではありません。ドキュメントは、言うweightSum Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children.
ジェフ・アクセルロッド

3
@JeffAxelrod:それは「指定されるべきではない」のですか?どうして?その理由はわかりません。したがって、指定する必要はありません。
2013

17
@MarcoW .:保守性のため、指定しないでください。Jeffが言ったように、weightSumをレイアウト内のウェイトの合計に等しく設定しても何も起こりませんが、誰かが将来それを変更した場合、レイアウトに不必要な修正が必要になるため、頭痛の原因となる可能性があります。変更されました。この回答は誤りであり、受け入れられるべき回答ではありません。
d370urn3ur 2013

3
weightSumパラメータの適切な説明が表示されないため、ドキュメントから:「これを使用して、たとえば、layout_weightを0.5に設定し、weightSumを1.0に設定することで、1つの子に使用可能な総スペースの50%を与えることができます。」developer.android.com/reference/android/widget/…を
Deepscorn

5
これは、weightSumを子の合計よりも大きい数に設定できるという考え方です。これにより、子供たちは利用可能な余分なスペースのすべてではなく一部を受け取ります。上記の例では、1人の子供がすべてのスペースではなく、利用可能なスペースの半分を継承します。
エドワードフォーク

175

superMとJeffの答えに加えて、

LinearLayoutに2つのビューがあり、1つ目はlayout_weightが1で、2つ目はlayout_weightが2で、weightSumが指定されていない場合、デフォルトでは、weightSumは3(子の重みの合計)と計算されます。最初のビューはスペースの1/3を占め、2番目のビューは2/3を占めます。

ただし、weightSumを5に指定すると、最初のスペースは1/5のスペースを使用し、2番目のスペースは2/5のスペースを使用します。したがって、合計で3/5のスペースがレイアウトによって占有され、残りは空のままになります。


2
同じことを探していましたが、ウェイトサムが定義されておらず、子ビューにウェイトが提供されている場合はどうでしょうか。それが自分で計算するというあなたの答えは、すべてをクリアしました
DeltaCap019

weightSumのあるレイアウトよりもRelativeLayoutの使用が推奨されているのは本当ですか?
ロバート

26

重みの合計は希望どおりに機能します(他の回答と同様に、親レイアウトのすべての重みを合計する必要はありません)。子ビューで、それが取る重量を指定します。指定することを忘れないでください

android:layout_width="0dp" 

以下は例です

    <LinearLayout
                android:layout_width="500dp"
                android:layout_height="20dp" >

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="3"
                    android:background="@android:color/holo_green_light"
                    android:gravity="center"
                    android:text="30%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="2"
                    android:background="@android:color/holo_blue_bright"
                    android:gravity="center"
                    android:text="20%"
                    android:textColor="@android:color/white" >
                </TextView>

                <TextView
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="5"
                    android:background="@android:color/holo_orange_dark"
                    android:gravity="center"
                    android:text="50%"
                    android:textColor="@android:color/white" >
                </TextView>
 </LinearLayout>

これは次のようになります

ここに画像の説明を入力してください


25

ドキュメントには、(私を強調し)、それは最高の例を含んでいると言います。

android:weightSum

最大重量合計を定義します。指定されていない場合、合計はすべての子のlayout_weightを追加して計算されます。これは与えるために、例えば、使用することができる単一のそれに0.5のlayout_weightを与え、1.0にweightSumを設定することにより、子供に利用可能な全容量の50%。

したがって、superMの例を修正するために、LinearLayout2つと1つImageViewsTextViewwith を含むwith with水平方向があると仮定します。をTextView固定サイズに定義ImageViewsし、残りのスペースを2つが均等に使用するようにします。

これを行うには、layout_weightImageViewに1を適用し、には何も適用せずTextView、にweightSumは2.0のa を適用しますLinearLayout


20

いくつかの実験の後、LinearLayoutのアルゴリズムは次のようになると思います。

weightSumが値に設定されていると仮定します。欠席の場合については、後で説明します。

最初に、weightSumLinearLayout の次元match_parentまたはfill_parent次元内の要素の数で分割します(例:のlayout_width場合orientation="horizontal")。この値w_mを各要素の重み乗数と呼びます。のデフォルト値weightSumは1.0なので、デフォルトの重み乗数はです1/n。ここnで、はfill_parent要素の数です。wrap_content要素は寄与しませんn

w_m = weightSum / #fill_parent

たとえば、weightSumが60で、fill_parent要素が3つある場合、加重乗数は20です。加重乗数は、たとえばlayout_width属性が存在しない場合のデフォルト値です。

次に、すべての要素の最大可能拡張が計算されます。まず、wrap_content要素はその内容に従って計算されます。それらの拡張は、親コンテナーの拡張から差し引かれます。残りを呼ぶことにしますexpansion_remainer。この残りは、fill_parentに従って要素間で分配されますlayout_weight

3番目に、すべてのfill_parent要素の展開は次のように計算されます。

w_m-(layout_weight / w_m)* maximum_possible_expansion

例:

weightSumが60 fill_parentで、重みが10、20、30の3つの要素がある場合、画面上のそれらの拡張は、親コンテナーの2 / 3、1 / 3、および0/3です。

weight | expansion
     0 | 3/3
    10 | 2/3
    20 | 1/3
    30 | 0/3
    40 | 0/3

最小拡張の上限は0です。最大拡張の上限は親サイズです。つまり、重みの上限は0です。

要素がに設定されている場合wrap_content、その展開が最初に計算され、残りの展開はfill_parent要素間の分布の影響を受けます。weightSumが設定されている場合、これは要素にlayout_weight影響を与えませんwrap_content。ただし、wrap_content要素が、その重みが低い要素重み乗数(たとえば、weightSum1の場合は0-1の間、または上記の例の場合は0-20の間)によって、表示領域から押し出すことができます。

weightSumも指定されていない場合は、set!の要素を含むすべてのlayout_weight値の合計として計算されます。要素を設定すると、要素の展開に影響を与える可能性があります。たとえば、負の重みは他の要素を縮小します。要素が配置される前に、上記の式が要素に適用されます。可能な最大の展開は、ラップされたコンテンツに応じた展開です。要素が収縮され、その後、残りのために可能な最大膨張要素が計算され、分配されます。wrap_contentlayout_weightwrap_contentfill_parentfill_parentwrap_contentwrap_contentfill_parent

これは、直感的でない結果につながる可能性があります。


10

指定されていない場合、合計はすべての子のlayout_weightを追加して計算されます。これを使用して、たとえば、layout_weightに0.5を指定し、weightSumを1.0に設定することで、1つの子に使用可能な総スペースの50%を割り当てることができます。「1.2」などの浮動小数点値である必要があります

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/main_rel"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:weightSum="2.0" >

        <RelativeLayout
            android:id="@+id/child_one"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#0000FF" >
        </RelativeLayout>

        <RelativeLayout
            android:id="@+id/child_two"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:background="#00FF00" >
        </RelativeLayout>

    </LinearLayout>

「「1.2」などの浮動小数点値の場合があります。」(developer.android.com/reference/android/widget/...
信じられない月

6

他に誰も言及していないように見えることの1つ:垂直 があるとしましょうLinearLayout。その内部のレイアウト/要素/ビューのウェイトが100%正しく機能するためには、それらすべてにlayout_heightプロパティが必要です(xmlに存在する必要があります)ファイル)に設定し0dpます。他の値が場合によっては混乱するようです。


1
android:layout_width = "match_parent"は通常0dpの代わりに使用されます
kc ochibili

どうしてこんなことに?私はあなたが正しいことを意味し、それはめちゃくちゃですが、高さを0 dpに設定すると問題が解決しました。その理由を知りたい。
Abdul Waheed 2016年

2

レイアウトの重みは比率のように機能します。たとえば、垂直レイアウトがあり、2つのアイテム(ボタンやテキストビューなど)がある場合、1つはそれぞれレイアウトの重み2を持ち、もう1つはレイアウトの重み3を持ちます。次に、最初の項目は画面/レイアウトの5部分のうち2部分を占め、もう1項目は5部分のうち3部分を占めます。ここで5は重量合計です。つまり、重みの合計は、レイアウト全体を定義された部分に分割します。 また、レイアウトウェイトは、事前定義された合計ウェイト合計のうち、特定のアイテムが占める割合を定義します。重量合計も手動で宣言できます。UIデザインに線形レイアウトを使用する場合、ボタン、テキストビュー、編集テキストなどはすべて、ウェイトサムとレイアウトウェイトを使用して編成されます。


1

開発者ドキュメントから

たとえば、これを使用し50%て、layout_weightを0.5設定し、weightSumをに設定することにより、使用可能な合計スペースの単一の子を指定できます1.0

@Shubhayu回答への追加

rest 3/5は、レイアウトを含む特定の部分を本当に必要としない他の子レイアウトに使用できます。

これはandroid:weightSumプロパティの潜在的な使用です。

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