Android: layout_weight หมายความว่าอย่างไร?


650

ฉันไม่เข้าใจวิธีการใช้คุณสมบัตินี้ ใครสามารถบอกฉันเพิ่มเติมเกี่ยวกับเรื่องนี้ได้บ้าง

คำตอบ:


860

ด้วยlayout_weightคุณสามารถระบุอัตราส่วนขนาดระหว่างหลายมุมมอง เช่นคุณมี a MapViewและ a tableซึ่งควรแสดงข้อมูลเพิ่มเติมบางอย่างบนแผนที่ แผนที่ควรใช้ 3/4 ของหน้าจอและตารางควรใช้ 1/4 ของหน้าจอ จากนั้นคุณจะตั้งค่าlayout_weightของmap3 เป็นและlayout_weightของtable1

เพื่อให้ได้งานคุณต้องตั้งความสูงหรือความกว้าง (ขึ้นอยู่กับทิศทางของคุณ) เป็น 0px


208
scratcher หัวจนกว่าคุณจะพูดถึงความสูง 0px!
JohnnyLambada

24
เพื่อกำหนดว่าจะได้รับผลกระทบจากน้ำหนักใด ความกว้างหรือความสูง
neteinstein

30
คุณต้องการ 0px ตัวอย่าง: คุณต้องการใช้ตารางที่มีสองคอลัมน์ที่มีขนาดเท่ากัน แต่ละแถวของตารางเป็นเค้าโครงเชิงเส้นแนวนอนที่มี "เซลล์ตาราง" สองอัน (ตัวอย่างเช่น TextViews) แต่ละอันมี layout_weight = .5 หากคุณระบุ layout_width = "wrap_content" บน "เซลล์ตาราง" ความกว้างเนื้อหาจะถูกเพิ่มเข้าไปในความกว้างที่คำนวณโดย layout_weight เซลล์ตารางจะมีขนาดแตกต่างกันทั้งหมดและคอลัมน์จะไม่เรียงแถวอย่างถูกต้อง ดังนั้นคุณต้องตั้ง layout_width = 0dp เพื่อให้ android ใช้ layout_weight ในการคำนวณความกว้างของเซลล์
eeeeaaii

3
@ โซเลซตอบช้า แต่เพื่อความสมบูรณ์ .. ดูเหมือนว่าแอตทริบิวต์น้ำหนักไม่ได้มีส่วนร่วมใน RelativeLayout ใช้งานได้กับ LinearLayout เท่านั้น หากคุณเห็นความต้องการ weigth บางทีวิธีที่จะไปคือการสร้าง LinearLayout (พร้อมน้ำหนัก) ภายใน RelativeLayout
bbv

1
layout_weight ใช้งานได้เฉพาะกับโครงร่างเชิงเส้นหรือใช้ได้กับทุกกลุ่มมุมมอง
meShakti

247

สรุปlayout_weightระบุจำนวนพื้นที่พิเศษในโครงร่างที่จะจัดสรรให้กับมุมมอง

LinearLayout รองรับการกำหนดน้ำหนักให้กับเด็กแต่ละคน คุณลักษณะนี้กำหนดค่า "ความสำคัญ" ให้กับมุมมองและอนุญาตให้ขยายเพื่อเติมพื้นที่ว่างที่เหลืออยู่ในมุมมองพาเรนต์ น้ำหนักเริ่มต้นของการดูคือศูนย์

การคำนวณเพื่อกำหนดพื้นที่ที่เหลืออยู่ระหว่างลูก

โดยทั่วไปสูตรคือ:

พื้นที่ที่กำหนดให้กับเด็ก = (น้ำหนักของเด็กแต่ละคน) / (ผลรวมของน้ำหนักของเด็กทุกคนใน Linear Layout)

ตัวอย่างที่ 1

หากมีกล่องข้อความสามกล่องและอีกสองกล่องมีน้ำหนักเป็น 1 ในขณะที่กล่องที่สามไม่มีน้ำหนัก (0) พื้นที่ที่เหลือจะถูกกำหนดดังนี้:

กล่องข้อความที่ 1 = 1 / (1 + 1 + 0)

กล่องข้อความที่สอง = 1 / (1 + 1 + 0)

กล่องข้อความที่ 3 = 0 / (1 + 1 + 0)

ตัวอย่างที่ 2

สมมติว่าเรามีป้ายข้อความและองค์ประกอบแก้ไขข้อความสองรายการในแถวแนวนอน ไม่มีการlayout_weightระบุป้ายกำกับดังนั้นจึงใช้พื้นที่ขั้นต่ำในการแสดงผล หากlayout_weightองค์ประกอบการแก้ไขข้อความทั้งสองรายการถูกตั้งค่าเป็น 1 ความกว้างที่เหลือในเค้าโครงหลักจะถูกแบ่งเท่า ๆ กัน (เพราะเราอ้างว่าพวกเขามีความสำคัญเท่าเทียมกัน)

คำนวณ:

ป้ายกำกับที่ 1 = 0 / (0 + 1 + 1)

กล่องข้อความที่สอง = 1 / (0 + 1 + 1)

กล่องข้อความที่ 3 = 1 / (0 + 1 + 1)

ถ้าแทนกล่องข้อความหนึ่งกล่องแรกมี a layout_weight1 และกล่องข้อความที่สองมี a layout_weight2 จากนั้นหนึ่งในสามของพื้นที่ว่างที่เหลือจะได้รับในช่องแรกและสองในสามเป็นที่สอง (เพราะเราอ้างสิทธิ์ที่สอง สิ่งหนึ่งสำคัญกว่า)

คำนวณ:

ป้ายกำกับที่ 1 = 0 / (0 + 1 + 2)

กล่องข้อความที่สอง = 1 / (0 + 1 + 2)

กล่องข้อความที่ 3 = 2 / (0 + 1 + 2)


บทความต้นฉบับ


19
คำอธิบายที่ดีกว่าคำตอบที่เลือกในปัจจุบัน
Shade

12
มีคำอธิบายง่ายๆ (ที่ฉันขอบคุณ) และรายละเอียดเล็ก ๆ น้อย ๆ (ซึ่งฉันชื่นชมในวิธีที่ต่างออกไป) พวกเขาทั้งคู่เป็นคำตอบที่ดี
cbmanica

3
ดังที่กล่าวไว้ในที่อื่นandroid:layout_width="0px"เป็นเรื่องสำคัญ นอกจากนี้น้ำหนักไม่จำเป็นต้องเป็นจำนวนเต็ม
ไบรอันไวท์

นี่เป็นเรื่องยากที่จะเข้าใจมากกว่าคำตอบที่เลือก แต่ให้คำตอบที่สมบูรณ์ - โดยเฉพาะอย่างยิ่งเมื่อบางมุมมองมีน้ำหนักและบางคนไม่มี นั่นเป็นกรณีการใช้งานขนาดใหญ่ที่ไม่ครอบคลุมโดยคำตอบที่เลือก
Acey

ที่ไม่weightSumมาถ่ายภาพแล้ว? มันเกี่ยวข้องกับเรื่องlayout_weightอะไรบ้าง?
eRaisedToX

72

การเพิ่มคำตอบอื่น ๆ สิ่งที่สำคัญที่สุดในการทำให้เรื่องนี้ทำงานคือการกำหนดความกว้างของเลย์เอาต์ (หรือความสูง) เป็น 0px

android:layout_width="0px"

มิฉะนั้นคุณจะเห็นขยะ


ฉันคิดว่ามันขึ้นอยู่กับว่าคุณต้องการซ่อนมุมมองที่ไม่ได้กำหนดน้ำหนักของพวกเขาหรือคุณต้องการแสดงให้พวกเขามีขนาดพอดีกับขนาดและปล่อยให้พื้นที่ว่างที่เหลืออยู่กับมุมมอง "ถ่วงน้ำหนัก"
Andrea Leganza

ถ้าฉันต้องตั้งค่าน้ำหนักทั้งแนวนอนและแนวตั้ง
Alston

40

หากมีมุมมองหลายทอดLinearLayoutแล้วlayout_weightจะช่วยให้พวกเขาในแต่ละขนาดสัดส่วน มุมมองที่มีlayout_weightค่า "น้ำหนัก" มากขึ้นก็จะได้พื้นที่มากขึ้น

นี่คือภาพเพื่อทำให้สิ่งต่าง ๆ ชัดเจนยิ่งขึ้น

ป้อนคำอธิบายรูปภาพที่นี่

ทฤษฎี

รูปแบบน้ำหนักคำที่เกี่ยวข้องกับแนวคิดของค่าเฉลี่ยถ่วงน้ำหนักในคณิตศาสตร์ มันเหมือนอยู่ในชั้นเรียนของวิทยาลัยที่การบ้านมีค่า 30% การเข้าร่วมมีค่า 10% กลางภาคมีค่า 20% และสุดท้ายคือ 40% คะแนนของคุณสำหรับชิ้นส่วนเหล่านั้นเมื่อถ่วงน้ำหนักร่วมกันให้คะแนนรวมของคุณ

ป้อนคำอธิบายรูปภาพที่นี่

มันเหมือนกันสำหรับน้ำหนักเค้าโครง ViewsในแนวนอนLinearLayoutแต่ละคนจะสามารถใช้เวลาถึงร้อยละหนึ่งของความกว้างทั้งหมด (หรือเปอร์เซ็นต์ของความสูงสำหรับแนวตั้งLinearLayout)

เลย์เอาต์

สิ่งLinearLayoutที่คุณใช้จะมีลักษณะเช่นนี้:

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <!-- list of subviews -->

</LinearLayout>

โปรดทราบว่าคุณต้องใช้สำหรับlayout_width="match_parent" LinearLayoutถ้าคุณใช้wrap_contentมันจะไม่ทำงาน นอกจากนี้โปรดทราบว่าlayout_weightไม่สามารถใช้งานได้กับมุมมองใน RelativeLayouts (ดูที่นี่และที่นี่เพื่อหาคำตอบ SO ที่เกี่ยวข้องกับปัญหานี้)

มุมมอง

แต่ละมุมมองในแนวนอนLinearLayoutมีลักษณะดังนี้:

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

โปรดทราบว่าคุณจำเป็นต้องใช้ร่วมกับlayout_width="0dp" layout_weight="1"การลืมสิ่งนี้ทำให้เกิดปัญหาผู้ใช้ใหม่มากมาย (ดูบทความนี้สำหรับผลลัพธ์ที่แตกต่างที่คุณสามารถทำได้โดยไม่ตั้งค่าความกว้างเป็น 0) หากมุมมองของคุณอยู่ในแนวตั้ง LinearLayoutคุณควรใช้layout_height="0dp"แน่นอน

ในButtonตัวอย่างด้านบนฉันตั้งค่าน้ำหนักเป็น 1 แต่คุณสามารถใช้ตัวเลขใดก็ได้ มันเป็นเพียงผลรวมที่สำคัญ คุณสามารถเห็นได้จากปุ่มสามแถวในภาพแรกที่ฉันโพสต์ตัวเลขต่างกันทั้งหมด แต่เนื่องจากสัดส่วนเท่ากันความกว้างถ่วงน้ำหนักจึงไม่เปลี่ยนแปลงในแต่ละแถว บางคนชอบใช้เลขทศนิยมที่มีผลรวมเป็น 1 เพื่อให้อยู่ในรูปแบบที่ซับซ้อนจะมีความชัดเจนว่าน้ำหนักของแต่ละส่วนคืออะไร

โน้ตตัวสุดท้าย หากคุณมีเลย์เอาต์ที่ซ้อนกันมากมายที่ใช้งานlayout_weightอาจเป็นผลเสียต่อประสิทธิภาพการทำงาน

พิเศษ

นี่คือเค้าโครง xml สำหรับภาพด้านบน:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="2" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="1" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="20"
            android:text="20" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="10"
            android:text="10" />

    </LinearLayout>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="android:layout_weight="
        android:textSize="24sp" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".50"
            android:text=".50" />

        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight=".25"
            android:text=".25" />

    </LinearLayout>

</LinearLayout>

1
ฉันมักจะสงสัยว่าทำไมผู้คนจำนวนมากไม่โพสต์ภาพเพื่อประกอบกับ XML ของพวกเขา มันง่ายต่อการเข้าใจภาพมากกว่ารหัส
AleksandrH

30

layout_weightบอก Android วิธีการกระจายของคุณViews LinearLayoutใน Android จะคำนวณสัดส่วนทั้งหมดที่ต้องการสำหรับViews ทั้งหมดที่มีน้ำหนักที่ระบุและวางแต่ละส่วนViewตามสัดส่วนของหน้าจอที่ระบุไว้ ในตัวอย่างต่อไป, Android เห็นว่าTextViews มีlayout_weightของ0(นี่เป็นค่าเริ่มต้น) และEditTexts มีlayout_weightของ2แต่ละคนขณะที่มีน้ำหนักของButton 1จัดสรรดังนั้น Android 'พอเพียง' พื้นที่ในการแสดงผลtvUsernameและtvPasswordแล้วแบ่งที่เหลือของความกว้างหน้าจอออกเป็น 5 ส่วนเท่า ๆ กันสองซึ่งจะจัดสรรให้กับetUsernameสองถึงetPasswordและส่วนสุดท้ายที่จะbLogin:

<LinearLayout android:orientation="horizontal" ...>

    <TextView android:id="@+id/tvUsername" 
    android:text="Username" 
    android:layout_width="wrap_content" ... />

    <EditText android:id="@+id/etUsername"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <TextView android:id="@+id/tvPassword"
    android:text="Password"
    android:layout_width="wrap_content" />

    <EditText android:id="@+id/etPassword"
    android:layout_width="0dp"
    android:layout_weight="2" ... />

    <Button android:id="@+id/bLogin"
    android:layout_width="0dp"
    android:layout_weight="1"
    android:text="Login"... />

</LinearLayout>

ดูเหมือนว่า:
การวางแนวแนวนอน และ
การวางแนวแนวตั้ง


ลิงก์ไม่สามารถใช้ได้อีกต่อไป หากคุณมีการอ้างอิงที่ดีอื่นโปรดอัปเดต
BinaryGuy

16

คิดว่าอย่างนั้นจะง่ายกว่า

หากคุณมี 3 ปุ่มและน้ำหนักของปุ่มอยู่ที่ 1,3,1 ดังนั้นมันจะทำงานเหมือนกับตารางใน HTML

ระบุ 5 ส่วนสำหรับบรรทัดนั้น: 1 ส่วนสำหรับปุ่ม 1, 3 ส่วนสำหรับปุ่ม 2 และ 1 ส่วนสำหรับปุ่ม 1

คำนึงถึง,


10

หนึ่งในคำอธิบายที่ดีที่สุดสำหรับฉันคืออันนี้ (จากการกวดวิชา Android มองหาขั้นตอนที่ 7) :

layout_weight ใช้ใน LinearLayouts เพื่อกำหนด "ความสำคัญ" ให้กับมุมมองภายในเค้าโครง มุมมองทั้งหมดมีเค้าโครงเริ่มต้นน้ำหนักเป็นศูนย์หมายความว่าพื้นที่บนหน้าจอมากเท่าที่จำเป็นต้องแสดง การกำหนดค่าที่สูงกว่าศูนย์จะแยกส่วนที่เหลือของพื้นที่ว่างในมุมมองพาเรนต์ตามค่าของ layout_weight แต่ละมุมมองและอัตราส่วนต่อมุมมอง layout_weight โดยรวมที่ระบุในโครงร่างปัจจุบันสำหรับองค์ประกอบนี้และมุมมองอื่น ๆ

ในการให้ตัวอย่าง: สมมติว่าเรามีป้ายข้อความและองค์ประกอบแก้ไขข้อความสองรายการในแถวแนวนอน ป้ายกำกับไม่มีการระบุ layout_weight ดังนั้นจึงต้องใช้พื้นที่ขั้นต่ำในการแสดงผล หาก layout_weight ขององค์ประกอบการแก้ไขข้อความทั้งสองถูกตั้งค่าเป็น 1 ความกว้างที่เหลือในเค้าโครงหลักจะถูกแบ่งเท่า ๆ กัน (เพราะเราอ้างว่ามันมีความสำคัญเท่าเทียมกัน) หากอันแรกมี layout_weight 1 และที่สองมี layout_weight 2 จากนั้นหนึ่งในสามของพื้นที่ที่เหลือจะมอบให้กับที่หนึ่งและสองในสามที่สอง (เพราะเราอ้างว่าอันที่สองสำคัญกว่า)



4

สำหรับเพิ่มเติม

สำหรับverticalการวางแนวอย่าลืมตั้งไว้heightที่ 0dp

android:layout_height="0dp"

สำหรับhorizontalการวางแนวอย่าลืมตั้งไว้widthที่ 0dp

android:layout_width="0dp"

3

โปรดดู weightSum ของ LinearLayout และ layout_weight ของแต่ละมุมมอง android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" layout_height ของพวกเขามีทั้ง 0px แต่ฉันไม่แน่ใจว่าเกี่ยวข้องกันหรือไม่

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="4">

<fragment android:name="com.example.SettingFragment"
    android:id="@+id/settingFragment"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    />

<Button
    android:id="@+id/dummy_button"
    android:layout_width="match_parent"
    android:layout_height="0px"
    android:layout_weight="2"
    android:text="DUMMY"
    />
</LinearLayout>

โปรดดู weightSum ของ LinearLayout และ layout_weight ของแต่ละมุมมอง android: weightSum = "4" android: layout_weight = "2" android: layout_weight = "2" layout_height ของพวกเขามีทั้ง 0px แต่ฉันไม่แน่ใจว่าเกี่ยวข้องกันหรือไม่
Ming Leung

0

รวมทั้งคำตอบจาก

Flo & rptwsthi และ roetzi

อย่าลืมที่จะเปลี่ยนของคุณlayout_width=0dp/pxมิฉะนั้นlayout_weightพฤติกรรมจะทำหน้าที่ตรงกันข้ามโดยมีจำนวนมากที่สุดครอบครองพื้นที่ที่เล็กที่สุดและจำนวนที่น้อยที่สุดจะครอบครองพื้นที่ที่ใหญ่ที่สุด

นอกจากนี้การผสมน้ำหนักบางส่วนจะทำให้รูปแบบบางอย่างไม่สามารถแสดงได้ (เนื่องจากอยู่เหนือพื้นที่ว่าง)

ระวังสิ่งนี้



-1

ตามชื่อที่แนะนำน้ำหนักเค้าโครงระบุจำนวนหรือเปอร์เซ็นต์ของพื้นที่ที่ฟิลด์หรือวิดเจ็ตเฉพาะควรใช้พื้นที่หน้าจอ ถ้าเราระบุน้ำหนักในแนวนอนแล้วเราจะต้องระบุ
ในทำนองเดียวกันถ้าเราระบุน้ำหนักในแนวตั้งแล้วเราจะต้องระบุ layout_width = 0px
layout_height = 0px

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.