Android là gì: weightSum trong Android và nó hoạt động như thế nào?


Câu trả lời:


132

Mỗi tài liệu, android:weightSumxác định tổng trọng lượng tối đa và được tính là tổng layout_weightcủa tất cả trẻ em nếu không được chỉ định rõ ràng.

Hãy xem xét một ví dụ với một LinearLayouthướng nằm ngang và 3 ImageViewsbên trong nó. Bây giờ chúng tôi muốn những thứ này ImageViewsluôn luôn có không gian bằng nhau. Để đạt được điều này, bạn có thể đặt layout_weighttừng cái ImageViewthành 1 và weightSumsẽ được tính bằng 3 như trong bình luận.

<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 rất hữu ích khi bố trí được hiển thị chính xác cho bất kỳ thiết bị nào, điều này sẽ không xảy ra nếu bạn đặt trực tiếp chiều rộng và chiều cao.


145
Đây không phải là một lời giải thích về mục đích của weightSum. Hành vi trong ví dụ của bạn sẽ giống hệt với weightSumbỏ qua và trên thực tế weightSum không nên được chỉ định trong kịch bản đó. Các tài liệu nói,weightSum Defines the maximum weight sum. If unspecified, the sum is computed by adding the layout_weight of all of the children.
Jeff Axelrod

3
@JeffAxelrod: Nó "không nên" được chỉ định? Tại sao? Tôi thấy không có lý do cho điều đó. Vì vậy, tôi chỉ muốn nói rằng nó không cần phải được chỉ định.
kêu

17
@MarcoW.: Không nên chỉ định vì khả năng bảo trì. Như Jeff đã nói, việc đặt weightSum bằng tổng trọng số bên trong bố cục sẽ không có gì, nhưng nếu ai đó thay đổi nó trong tương lai thì nó có thể gây đau đầu vì bây giờ có một công cụ sửa đổi không cần thiết cho bố cục sẽ phải tìm và thay đổi. Câu trả lời này không chính xác và không nên là câu trả lời được chấp nhận.
d370urn3ur

3
Đừng thấy một lời giải thích tốt về tham số weightSum, vì vậy, từ các tài liệu: "Chẳng hạn, điều này có thể được sử dụng để cung cấp cho một đứa trẻ 50% tổng dung lượng có sẵn bằng cách đặt cho nó một layout_ weight 0,5 và đặt weightSum thành 1.0." Xem developer.android.com/reference/android/widget/ khăn
Deepscorn 13/03/2015

5
Ý tưởng là bạn có thể đặt weightSum thành một số cao hơn tổng của trẻ em. Điều này khiến trẻ nhận được một số nhưng không phải tất cả không gian thừa có sẵn. Trong ví dụ trên, đứa con độc thân của bạn sẽ thừa hưởng một nửa không gian có sẵn thay vì tất cả.
Edward Falk

175

Thêm vào câu trả lời của superM và Jeff,

Nếu có 2 lượt xem trong linearLayout, thì lần đầu tiên có layout_ weight là 1, lần thứ hai có layout_ weight là 2 và không có weightSum được chỉ định, theo mặc định, weightSum được tính là 3 (tổng trọng số của trẻ em) và chế độ xem thứ nhất chiếm 1/3 không gian trong khi chế độ thứ hai chiếm 2/3.

Tuy nhiên, nếu chúng ta chỉ định weightSum là 5, thì cái đầu tiên sẽ chiếm 1/5 không gian trong khi cái thứ hai sẽ chiếm 2/5. Vì vậy, tổng cộng 3/5 không gian sẽ bị chiếm bởi bố cục giữ phần còn lại trống.


2
Tôi đang tìm kiếm điều tương tự, rằng điều gì xảy ra nếu trọng số không được xác định và trọng số được cung cấp cho các quan điểm trẻ em. Câu trả lời của bạn rằng nó tự tính toán mọi thứ đã bị xóa
DeltaCap019

Có đúng là nên sử dụng RelativeLayout hơn Bố cục với weightSum không?
Robert

26

Tổng trọng số hoạt động chính xác như bạn muốn (giống như các câu trả lời khác mà bạn không phải tính tổng tất cả các trọng số trên bố trí cha mẹ). Trên chế độ xem con xác định trọng lượng bạn muốn nó mất. Đừng quên chỉ định

android:layout_width="0dp" 

Sau đây là một ví dụ

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

Điều này sẽ giống như

nhập mô tả hình ảnh ở đây


25

Các tài liệu nói rằng nó tốt nhất và bao gồm một ví dụ, (làm nổi bật của tôi).

android: trọng lượng

Xác định tổng trọng lượng tối đa. Nếu không được chỉ định, tổng được tính bằng cách thêm layout_ weight của tất cả các con. Điều này có thể được sử dụng ví dụ để cung cấp cho một đơn con 50% tổng số không gian có sẵn bằng cách cho nó một layout_weight 0,5 và thiết lập weightSum đến 1.0.

Vì vậy, để sửa ví dụ của superM, giả sử bạn có một LinearLayouthướng nằm ngang chứa hai ImageViewsvà một TextViewvới. Bạn xác định TextViewđể có một kích thước cố định và bạn muốn cả hai ImageViewschiếm không gian còn lại như nhau.

Để thực hiện điều này, bạn sẽ áp dụng layout_weight1 cho mỗi ImageView, không có gì trên TextViewweightSum2.0 trên LinearLayout.


20

Sau một số thử nghiệm, tôi nghĩ thuật toán cho linearLayout là thế này:

Giả sử rằng weightSumđược đặt thành một giá trị. Các trường hợp vắng mặt sẽ được thảo luận sau.

Đầu tiên, chia weightSumsố lượng phần tử với kích thước match_parenthoặc fill_parenttheo thứ nguyên của linearLayout (ví dụ: layout_widthcho orientation="horizontal"). Chúng tôi sẽ gọi giá trị này là hệ số nhân w_mcho mỗi yếu tố. Giá trị mặc định cho weightSumlà 1.0, vì vậy hệ số nhân trọng lượng mặc định là 1/n, nsố lượng fill_parentphần tử; wrap_contentcác yếu tố không đóng góp cho n.

w_m = weightSum / #fill_parent

Ví dụ: khi weightSum60 và có 3 fill_parentphần tử, hệ số trọng số là 20. Hệ số trọng số là giá trị mặc định, ví dụ: layout_widthnếu không có thuộc tính.

Thứ hai, sự mở rộng tối đa có thể của mọi yếu tố được tính toán. Đầu tiên, các wrap_contentyếu tố được tính toán theo nội dung của chúng. Sự mở rộng của họ được khấu trừ từ việc mở rộng container mẹ. Chúng tôi sẽ gọi cho người ở lại expansion_remainer. Phần còn lại này được phân phối giữa fill_parentcác yếu tố theo họ layout_weight.

Thứ ba, việc mở rộng mọi fill_parentphần tử được tính là:

w_m - (layout_ weight / w_m) * Maximum_possible_Exansion

Thí dụ:

Nếu weightSumlà 60 và có 3 fill_parentyếu tố với các số 10, 20 và 30, thì độ mở rộng của chúng trên màn hình là 2/3, 1/3 và 0/3 của thùng chứa mẹ.

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

Mở rộng tối thiểu được giới hạn ở mức 0. Mở rộng tối đa được giới hạn ở kích thước cha, tức là các trọng số được giới hạn ở 0.

Nếu một phần tử được đặt thành wrap_content, phần mở rộng của nó được tính toán trước và phần mở rộng còn lại phải chịu sự phân phối giữa các fill_parentphần tử. Nếu weightSumđược đặt, điều này dẫn đến layout_weightkhông có ảnh hưởng đến wrap_contentcác yếu tố. Tuy nhiên, wrap_contentcác phần tử vẫn có thể được đẩy ra khỏi vùng nhìn thấy bởi các phần tử có trọng lượng thấp hơn số nhân trọng lượng(ví dụ từ 0-1 choweightSum = 1 hoặc trong khoảng 0-20 cho ví dụ trên).

Nếu không weightSumđược chỉ định, nó được tính là tổng của tất cả các layout_weightgiá trị, bao gồm các phần tử có wrap_contenttập hợp! Vì vậy, đã layout_weightthiết lập trên wrap_contentcác yếu tố, có thể ảnh hưởng đến việc mở rộng của họ. Ví dụ, một trọng lượng âm sẽ thu nhỏ các fill_parentyếu tố khác . Trước khi các fill_parentyếu tố được trình bày, công thức trên sẽ được áp dụng cho wrap_contentcác yếu tố, với khả năng mở rộng tối đa có thể là sự mở rộng của chúng theo nội dung được bao bọc. Các wrap_contentphần tử sẽ được thu nhỏ và sau đó mở rộng tối đa có thể cho các fill_parentphần tử còn lại được tính toán và phân phối.

Điều này có thể dẫn đến kết quả không trực quan.


10

Nếu không được chỉ định, tổng được tính bằng cách thêm layout_ weight của tất cả các con. Ví dụ, điều này có thể được sử dụng để cung cấp cho một đứa trẻ 50% tổng dung lượng có sẵn bằng cách đặt cho nó một layout_ weight là 0,5 và đặt weightSum thành 1.0. Phải là một giá trị dấu phẩy động, chẳng hạn như "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>

'Có thể là giá trị dấu phẩy động, chẳng hạn như "1.2".' ( developer.android.com/reference/android/widget/
Sự đáng kinh ngạc ngày

6

Một điều mà dường như không ai khác đề cập: giả sử bạn có chiều dọc LinearLayout , do đó, để các trọng số trong bố cục / phần tử / chế độ xem bên trong nó hoạt động đúng 100% - tất cả chúng phải có thuộc layout_heighttính (phải tồn tại trong xml của bạn tập tin) được đặt thành 0dp. Có vẻ như bất kỳ giá trị nào khác sẽ làm mọi thứ rối tung lên trong một số trường hợp.


1
android: layout_creen = "match_parent" thường được sử dụng thay vì 0dp
kc ochibili

tại sao lại như vậy Tôi có nghĩa là bạn đúng nó đang gây rối, nhưng thiết lập chiều cao thành 0 dp đã giải quyết vấn đề của tôi. tôi sẽ biết lý do.
Abdul Waheed

2

Trọng lượng bố trí hoạt động như một tỷ lệ. Ví dụ: nếu có bố cục dọc và có hai mục (chẳng hạn như nút hoặc xem văn bản), một mục có bố cục trọng lượng 2 và mục còn lại có trọng số bố cục 3 tương ứng. Sau đó, mục thứ 1 sẽ chiếm 2 trên 5 phần màn hình / bố cục và phần còn lại 3 trên 5 phần. Ở đây 5 là tổng trọng lượng. tức là Tổng trọng lượng chia toàn bộ bố cục thành các phần xác định. Và Trọng lượng bố trí xác định bao nhiêu phần mà vật phẩm cụ thể chiếm trong tổng số Trọng lượng được xác định trước. Tổng trọng lượng có thể được khai báo bằng tay là tốt. Các nút, xem xét văn bản, edittexts, v.v ... tất cả đều được tổ chức bằng trọng số và trọng lượng bố cục khi sử dụng bố cục tuyến tính cho thiết kế UI.


1

Từ tài liệu phát triển

Ví dụ, điều này có thể được sử dụng để cung cấp cho một đứa trẻ 50%trong tổng số không gian có sẵn bằng cách cung cấp cho nó một 0.5layout_ weight of và đặt weightSum thành 1.0.

Ngoài câu trả lời @Shubhayu

phần còn lại 3/5có thể được sử dụng cho các bố cục con khác mà thực sự không cần bất kỳ phần cụ thể nào trong bố cục chứa.

đây là tiềm năng sử dụng android:weightSumtài sản.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.