เลย์เอาต์ที่ปรับเปลี่ยน/ตอบสนองได้มอบประสบการณ์การใช้งานที่ดีที่สุดให้แก่ผู้ใช้ไม่ว่าจะใช้หน้าจอขนาดใด ใช้เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์/ที่ปรับเปลี่ยนได้เพื่อให้แอปแบบหน้าเว็บรองรับขนาด การวางแนว และการกำหนดค่าการแสดงผลทั้งหมด รวมถึงการกำหนดค่าที่ปรับขนาดได้ เช่น โหมดหลายหน้าต่าง
การออกแบบที่ปรับเปลี่ยนตามอุปกรณ์
ขั้นตอนแรกในการรองรับรูปแบบของอุปกรณ์ที่หลากหลายคือการสร้างเลย์เอาต์ที่ปรับเปลี่ยนตามพื้นที่ในการแสดงผลที่มีให้สำหรับแอป
ConstraintLayout
วิธีที่ดีที่สุดในการสร้างเลย์เอาต์ที่ตอบสนองตามอุปกรณ์คือการใช้ ConstraintLayout
เป็นเลย์เอาต์พื้นฐานสำหรับ UI ConstraintLayout
ช่วยให้คุณระบุตำแหน่งและขนาดของมุมมองแต่ละรายการตามความสัมพันธ์เชิงพื้นที่กับมุมมองอื่นๆ ในเลย์เอาต์ จากนั้นมุมมองทั้งหมดจะย้ายและปรับขนาดพร้อมกันได้เมื่อพื้นที่แสดงผลเปลี่ยนแปลง
วิธีที่ง่ายที่สุดในการสร้างเลย์เอาต์ด้วย ConstraintLayout
คือการใช้เครื่องมือแก้ไขเลย์เอาต์ใน Android Studio เครื่องมือแก้ไขเลย์เอาต์ช่วยให้คุณลากมุมมองใหม่ไปยังเลย์เอาต์ ใช้ข้อจำกัดที่เกี่ยวข้องกับมุมมองหลักและมุมมองพี่น้อง รวมถึงตั้งค่าพร็อพเพอร์ตี้ของมุมมองได้โดยไม่ต้องแก้ไข XML ด้วยตนเอง
![](https://developer.android.com/static/images/screens_support/layout-editor_2x.png?authuser=4&hl=th)
ConstraintLayout
ดูข้อมูลเพิ่มเติมได้ที่สร้าง UI ที่ปรับเปลี่ยนตามอุปกรณ์ด้วย ConstraintLayout
ความกว้างและความสูงที่ปรับเปลี่ยนตามอุปกรณ์
หากต้องการให้เลย์เอาต์ปรับเปลี่ยนตามขนาดการแสดงผลต่างๆ ให้ใช้ wrap_content
, match_parent
หรือ 0dp (match constraint)
สำหรับความกว้างและความสูงของคอมโพเนนต์มุมมองแทนค่าที่กำหนดไว้ล่วงหน้า ดังนี้
wrap_content
: มุมมองจะตั้งค่าขนาดให้พอดีกับเนื้อหาที่มีmatch_parent
: มุมมองจะขยายมากที่สุดภายในมุมมองหลัก0dp (match constraint)
: ในConstraintLayout
คล้ายกับmatch_parent
มุมมองจะใช้พื้นที่ว่างทั้งหมดภายในข้อจำกัดของมุมมอง
เช่น
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/lorem_ipsum" />
รูปที่ 4 แสดงวิธีที่ความกว้างและความสูงของ TextView
ปรับตามความกว้างของจอแสดงผลที่เปลี่ยนแปลงตามการวางแนวของอุปกรณ์
![](https://developer.android.com/static/images/screens_support/layout-match-parent_2x.png?authuser=4&hl=th)
TextView
ที่ปรับเปลี่ยนตามพื้นที่โฆษณา
TextView
จะตั้งค่าความกว้างให้เต็มพื้นที่ว่างทั้งหมด (match_parent
) และความสูงให้เท่ากับพื้นที่ที่จำเป็นสำหรับความสูงของข้อความที่บรรจุอยู่ (wrap_content
) ซึ่งช่วยให้มุมมองปรับขนาดการแสดงผลและจำนวนข้อความที่แตกต่างกันได้
หากใช้ LinearLayout
คุณยังขยายมุมมองย่อยตามน้ำหนักเลย์เอาต์ได้ด้วยเพื่อให้มุมมองเต็มพื้นที่ว่างตามสัดส่วน อย่างไรก็ตาม การใช้น้ำหนักใน LinearLayout
ที่ฝังอยู่จะทำให้ระบบต้องเรียกใช้เลย์เอาต์หลายครั้งเพื่อกำหนดขนาดสำหรับแต่ละมุมมอง ซึ่งจะทำให้ประสิทธิภาพของ UI ช้าลง
ConstraintLayout
สร้างเลย์เอาต์ได้เกือบทั้งหมดด้วย
LinearLayout
โดยไม่ส่งผลกระทบต่อประสิทธิภาพ ดังนั้นให้แปลง LinearLayout
ที่ฝังอยู่เป็น ConstraintLayout
จากนั้นคุณสามารถกําหนดเลย์เอาต์ที่มีน้ำหนักด้วยเชนข้อจํากัด
การออกแบบที่ปรับเปลี่ยนได้
เลย์เอาต์ของแอปควรปรับเปลี่ยนตามขนาดการแสดงผลที่แตกต่างกันเสมอ อย่างไรก็ตาม เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์ก็อาจไม่สามารถมอบประสบการณ์การใช้งานที่ดีที่สุดในอุปกรณ์ทุกเครื่องหรือจอแสดงผลโหมดหลายหน้าต่าง เช่น UI ที่คุณออกแบบมาสำหรับโทรศัพท์อาจให้ประสบการณ์การใช้งานที่ไม่เหมาะสมกับผู้ใช้ในแท็บเล็ต การออกแบบที่ปรับเปลี่ยนได้จะมีเลย์เอาต์ทางเลือกที่เพิ่มประสิทธิภาพสำหรับขนาดการแสดงผลที่แตกต่างกัน
SlidingPaneLayout สำหรับ UI รายละเอียดรายการ
โดยปกติแล้ว UI รายการแบบละเอียดจะให้ประสบการณ์การใช้งานที่แตกต่างกันในหน้าจอขนาดต่างๆ ในหน้าจอขนาดใหญ่ แผงรายการและแผงรายละเอียดมักจะอยู่เคียงข้างกัน เมื่อเลือกรายการในรายการ ข้อมูลรายการจะแสดงในแผงรายละเอียดโดยไม่มีการเปลี่ยนแปลง UI โดยแผงทั้ง 2 แผงจะยังคงอยู่เคียงข้างกัน อย่างไรก็ตาม ในหน้าจอขนาดเล็ก แผง 2 แผงจะแสดงแยกกัน โดยแต่ละแผงจะกินพื้นที่ทั้งหน้าจอ เมื่อเลือกรายการในแผงรายการแล้ว แผงรายละเอียด (ซึ่งมีข้อมูลของรายการที่เลือก) จะแทนที่แผงรายการ การนําทางกลับจะแทนที่แผงรายละเอียดด้วยรายการ
SlidingPaneLayout
จัดการตรรกะในการระบุว่าประสบการณ์ของผู้ใช้แบบใดเหมาะสําหรับขนาดกรอบปัจจุบัน
<?xml version="1.0" encoding="utf-8"?>
<androidx.slidingpanelayout.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="280dp"
android:layout_height="match_parent"
android:layout_gravity="start" />
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_weight="1"
app:defaultNavHost="true"
app:navGraph="@navigation/item_navigation" />
</androidx.slidingpanelayout.widget.SlidingPaneLayout>
แอตทริบิวต์ layout_width
และ layout_weight
ของมุมมอง 2 รายการที่อยู่ใน SlidingPaneLayout
จะกำหนดลักษณะการทํางานของ SlidingPaneLayout
ในตัวอย่างนี้ หากหน้าต่างมีขนาดใหญ่พอ (กว้างอย่างน้อย 580dp) เพื่อแสดงทั้ง 2 มุมมอง แผงจะแสดงคู่กัน แต่หากความกว้างของหน้าต่างน้อยกว่า 580dp แผงจะเลื่อนทับกันเพื่อใช้พื้นที่ทั้งหน้าต่างแอป
หากความกว้างของหน้าต่างมากกว่าความกว้างขั้นต่ำทั้งหมดที่ระบุ (580dp) ระบบจะใช้ค่า layout_weight
เพื่อปรับขนาดของ 2 แผงตามสัดส่วน ในตัวอย่างนี้ แผงรายการจะกว้าง 280dp เสมอเนื่องจากไม่มีน้ำหนัก
อย่างไรก็ตาม แผงรายละเอียดจะเติมเต็มพื้นที่แนวนอนที่เกิน 580dp เสมอเนื่องจากการตั้งค่า layout_weight
ของมุมมอง
ทรัพยากรเลย์เอาต์สำรอง
หากต้องการปรับการออกแบบ UI ให้เหมาะกับขนาดการแสดงผลที่หลากหลาย ให้ใช้เลย์เอาต์อื่นที่ระบุโดยตัวระบุทรัพยากร
![](https://developer.android.com/static/images/screens_support/sizes-phone-tablet_2x.png?authuser=4&hl=th)
คุณสามารถระบุเลย์เอาต์ที่ปรับเปลี่ยนตามหน้าจอได้โดยสร้างไดเรกทอรี res/layout/
เพิ่มเติมในซอร์สโค้ดของแอป สร้างไดเรกทอรีสําหรับการกําหนดค่าหน้าจอแต่ละรายการที่ต้องใช้เลย์เอาต์ที่แตกต่างกัน จากนั้นเพิ่มตัวระบุการกําหนดค่าหน้าจอต่อท้ายชื่อไดเรกทอรี layout
(เช่น layout-w600dp
สําหรับหน้าจอที่มีความกว้าง 600 dp)
ตัวระบุการกําหนดค่าแสดงถึงพื้นที่ในการแสดงผลที่มองเห็นได้สําหรับ UI ของแอป ระบบจะพิจารณาการตกแต่งระบบ (เช่น แถบนําทาง) และการเปลี่ยนแปลงการกําหนดค่าหน้าต่าง (เช่น โหมดหลายหน้าต่าง) เมื่อเลือกเลย์เอาต์สําหรับแอป
หากต้องการสร้างเลย์เอาต์อื่นใน Android Studio โปรดดูใช้ตัวแปรเลย์เอาต์เพื่อเพิ่มประสิทธิภาพสำหรับหน้าจอต่างๆ ในหัวข้อพัฒนา UI ด้วยมุมมอง
ตัวระบุความกว้างที่เล็กที่สุด
ตัวระบุขนาดหน้าจอความกว้างที่เล็กที่สุดช่วยให้คุณระบุเลย์เอาต์อื่นสำหรับจอแสดงผลที่มีความกว้างขั้นต่ำซึ่งวัดเป็นพิกเซลแบบไม่ขึ้นอยู่กับความหนาแน่น (dp)
การอธิบายขนาดหน้าจอเป็นหน่วยวัด dp จะช่วยให้ Android ช่วยคุณสร้างเลย์เอาต์ที่ออกแบบมาสำหรับมิติข้อมูลการแสดงผลที่เฉพาะเจาะจงได้โดยไม่ต้องกังวลเกี่ยวกับความหนาแน่นของพิกเซลที่แตกต่างกัน
เช่น คุณสามารถสร้างเลย์เอาต์ชื่อ main_activity
ที่ปรับให้เหมาะกับโทรศัพท์และแท็บเล็ตโดยการสร้างไฟล์เวอร์ชันต่างๆ ในไดเรกทอรีต่างๆ ดังนี้
res/layout/main_activity.xml # For phones (smaller than 600dp smallest width) res/layout-sw600dp/main_activity.xml # For 7" tablets (600dp wide or wider)
ตัวระบุความกว้างที่เล็กที่สุดจะระบุขนาดที่เล็กที่สุดของจอแสดงผล 2 ด้าน โดยไม่คำนึงถึงการวางแนวปัจจุบันของอุปกรณ์ ดังนั้นจึงเป็นวิธีระบุขนาดจอแสดงผลโดยรวมที่ใช้ได้กับเลย์เอาต์
ค่าความกว้างที่เล็กที่สุดอื่นๆ สอดคล้องกับขนาดหน้าจอทั่วไปดังนี้
- 320dp: หน้าจอโทรศัพท์ขนาดเล็ก (240x320 ldpi, 320x480 mdpi, 480x800 hdpi ฯลฯ)
- 480dp: หน้าจอโทรศัพท์ขนาดใหญ่ ~5" (480x800 mdpi)
- 600dp: แท็บเล็ตขนาด 7 นิ้ว (600x1024 mdpi)
- 720dp: แท็บเล็ตขนาด 10 นิ้ว (720x1280 mdpi, 800x1280 mdpi ฯลฯ)
รูปภาพต่อไปนี้แสดงมุมมองโดยละเอียดมากขึ้นว่าความกว้าง dp ของหน้าจอต่างๆ สอดคล้องกับขนาดและการวางแนวหน้าจอที่แตกต่างกันอย่างไร
![](https://developer.android.com/static/images/screens_support/layout-adaptive-breakpoints_2x.png?authuser=4&hl=th)
ค่าสำหรับตัวระบุความกว้างน้อยที่สุดคือ dp เนื่องจากสิ่งสำคัญคือปริมาณพื้นที่ในการแสดงผลที่มีให้หลังจากระบบพิจารณาความหนาแน่นของพิกเซลแล้ว (ไม่ใช่ความละเอียดพิกเซลดิบ)
ขนาดที่คุณระบุโดยใช้ตัวระบุทรัพยากร เช่น ความกว้างที่เล็กที่สุดนั้นไม่ใช่ขนาดหน้าจอจริง แต่ระบุความกว้างหรือความสูงในหน่วย dp ที่ใช้ได้กับหน้าต่างของแอป ระบบ Android อาจใช้พื้นที่บางส่วนของหน้าจอสำหรับ UI ของระบบ (เช่น แถบระบบที่ด้านล่างของหน้าจอหรือแถบสถานะที่ด้านบน) ดังนั้นพื้นที่บางส่วนของหน้าจอจึงอาจไม่พร้อมใช้งานสำหรับเลย์เอาต์ของคุณ หากใช้แอปในโหมดหลายหน้าต่าง แอปจะมีสิทธิ์เข้าถึงเฉพาะขนาดของหน้าต่างที่มีแอปเท่านั้น เมื่อปรับขนาดหน้าต่าง ระบบจะทริกเกอร์การเปลี่ยนแปลงการกำหนดค่าด้วยขนาดหน้าต่างใหม่ ซึ่งจะช่วยให้ระบบเลือกไฟล์เลย์เอาต์ที่เหมาะสมได้ ดังนั้น ขนาดตัวระบุทรัพยากรที่คุณประกาศควรระบุเฉพาะพื้นที่ที่แอปของคุณต้องใช้เท่านั้น ระบบจะพิจารณาพื้นที่ที่ UI ของระบบใช้เมื่อจัดสรรพื้นที่สำหรับเลย์เอาต์ของคุณ
ตัวคําจํากัดความกว้างที่ใช้ได้
คุณอาจต้องเปลี่ยนเลย์เอาต์ตามความกว้างหรือความสูงที่มีแทนที่จะเปลี่ยนตามความกว้างของจอแสดงผลที่น้อยที่สุด เช่น คุณอาจต้องการใช้เลย์เอาต์แบบ 2 แผงเมื่อใดก็ตามที่หน้าจอมีความกว้างอย่างน้อย 600dp ซึ่งอาจเปลี่ยนแปลงได้ขึ้นอยู่กับว่าอุปกรณ์อยู่ในแนวนอนหรือแนวตั้ง ในกรณีนี้ คุณควรใช้ตัวระบุความกว้างที่พร้อมจำหน่าย ดังนี้
res/layout/main_activity.xml # For phones (smaller than 600dp available width) res/layout-w600dp/main_activity.xml # For 7" tablets or any screen with 600dp available width # (possibly landscape phones)
หากความสูงที่ใช้ได้เป็นสิ่งที่น่ากังวลสำหรับแอป คุณสามารถใช้ตัวระบุความสูงที่ใช้ได้ เช่น layout-h600dp
สำหรับหน้าจอที่มีความสูงของหน้าจออย่างน้อย 600 DP
ตัวระบุการวางแนว
แม้ว่าคุณอาจรองรับรูปแบบขนาดทั้งหมดได้โดยใช้เฉพาะการรวมตัวระบุความกว้างน้อยที่สุดและความกว้างที่ใช้ได้ แต่คุณอาจต้องเปลี่ยนประสบการณ์ของผู้ใช้ด้วยเมื่อผู้ใช้สลับระหว่างการวางแนวตั้งและแนวนอน
โดยคุณสามารถเพิ่มตัวระบุ port
หรือ land
ลงในชื่อไดเรกทอรีเลย์เอาต์ได้ เพียงตรวจสอบว่าตัวระบุการวางแนวอยู่หลังตัวระบุขนาด
เช่น
res/layout/main_activity.xml # For phones res/layout-land/main_activity.xml # For phones in landscape res/layout-sw600dp/main_activity.xml # For 7" tablets res/layout-sw600dp-land/main_activity.xml # For 7" tablets in landscape
ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวระบุการกําหนดค่าหน้าจอทั้งหมดได้ที่ภาพรวมแหล่งข้อมูลแอป
คลาสขนาดหน้าต่าง
Window Size Class คือจุดพักของวิวพอร์ตที่ช่วยให้คุณสร้างเลย์เอาต์ที่ปรับเปลี่ยนได้ เบรกพอยท์จะระบุพื้นที่แสดงผลที่พร้อมใช้งานสำหรับแอปของคุณเป็นกะทัดรัด กลาง หรือขยาย ความกว้างและความสูงจะระบุแยกกันเพื่อให้แอปมี Window Size Class สำหรับความกว้างและ Window Size Class สำหรับความสูงเสมอ
หากต้องการใช้เลย์เอาต์แบบปรับเปลี่ยนได้แบบเป็นโปรแกรม ให้ทําดังนี้
- สร้างทรัพยากรเลย์เอาต์ตามจุดหยุดพักของคลาสขนาดหน้าต่าง
- คํานวณคลาสขนาดหน้าต่างของแอปในด้านความกว้างและความสูงโดยใช้ฟังก์ชัน
WindowSizeClass#compute()
จากไลบรารี Jetpack WindowManager - ขยายทรัพยากรเลย์เอาต์สำหรับคลาสขนาดหน้าต่างปัจจุบัน
ดูข้อมูลเพิ่มเติมได้ที่ชั้นเรียนขนาดกรอบเวลา
คอมโพเนนต์ UI แบบโมดูลโดยใช้ส่วนย่อย
เมื่อออกแบบแอปสำหรับการแสดงผลหลายขนาด ให้ใช้ Fragment เพื่อดึงข้อมูลตรรกะ UI ของคุณออกเป็นคอมโพเนนต์แยกต่างหากเพื่อให้แน่ใจว่าคุณไม่ได้ทำซ้ำลักษณะการทำงานของ UI ในกิจกรรมต่างๆ โดยไม่จำเป็น จากนั้นคุณสามารถรวมข้อมูลโค้ดเพื่อสร้างเลย์เอาต์หลายแผงบนหน้าจอขนาดใหญ่ หรือจะวางข้อมูลโค้ดไว้ในกิจกรรมแยกต่างหากบนหน้าจอขนาดเล็กก็ได้
เช่น รูปแบบรายการแบบมีรายละเอียด (ดูSlidingPaneLayout ด้านบน) อาจใช้กับข้อมูลโค้ดที่หนึ่งซึ่งมีรายการ และข้อมูลโค้ดอีกรายการซึ่งมีรายละเอียดรายการ บนหน้าจอขนาดใหญ่ ข้อมูลโค้ดจะแสดงคู่กัน ส่วนบนหน้าจอขนาดเล็ก ข้อมูลโค้ดจะแสดงทีละรายการจนเต็มหน้าจอ
ดูข้อมูลเพิ่มเติมได้ที่ภาพรวมข้อมูลโค้ด
การฝังกิจกรรม
หากแอปประกอบด้วยกิจกรรมหลายรายการ การฝังกิจกรรมจะช่วยให้คุณสร้าง UI แบบปรับเปลี่ยนได้ง่ายๆ
การฝังกิจกรรมจะแสดงกิจกรรมหลายรายการหรือหลายอินสแตนซ์ของกิจกรรมเดียวกันพร้อมกันในหน้าต่างงานของแอปพลิเคชัน บนหน้าจอขนาดใหญ่ กิจกรรมจะแสดงคู่กัน ส่วนบนหน้าจอขนาดเล็ก กิจกรรมจะซ้อนกัน
คุณกำหนดวิธีแสดงกิจกรรมของแอปได้โดยการสร้างไฟล์การกำหนดค่า XML ซึ่งระบบจะใช้เพื่อกำหนดการแสดงผลที่เหมาะสมตามขนาดหน้าจอ หรือจะเรียกใช้ Jetpack WindowManager APIก็ได้
การฝังกิจกรรมรองรับการเปลี่ยนแปลงการวางแนวของอุปกรณ์และอุปกรณ์แบบพับได้ รวมถึงการซ้อนและเลิกซ้อนกิจกรรมเมื่ออุปกรณ์หมุนหรือพับออกและกางออก
ดูข้อมูลเพิ่มเติมได้ที่การฝังกิจกรรม
ขนาดหน้าจอและสัดส่วนภาพ
ทดสอบแอปในหน้าจอขนาดต่างๆ และอัตราส่วนภาพเพื่อให้แน่ใจว่า UI ปรับขนาดได้อย่างถูกต้อง
Android 10 (API ระดับ 29) ขึ้นไปรองรับสัดส่วนภาพได้หลากหลาย รูปแบบของอุปกรณ์แบบพับได้อาจแตกต่างกันไปตั้งแต่หน้าจอสูงและแคบ เช่น 21:9 เมื่อพับไปจนถึงสัดส่วนภาพสี่เหลี่ยมจัตุรัส 1:1 เมื่อกางออก
โปรดทดสอบแอปสำหรับสัดส่วนภาพหน้าจอต่อไปนี้ให้ได้มากที่สุดเพื่อให้เข้ากันได้กับอุปกรณ์จำนวนมากที่สุด
![](https://developer.android.com/static/images/guide/topics/ui/foldables/fold-screen-ratios.png?authuser=4&hl=th)
หากไม่มีสิทธิ์เข้าถึงอุปกรณ์ที่มีหน้าจอทุกขนาดที่ต้องการทดสอบ คุณสามารถใช้โปรแกรมจำลอง Android เพื่อจำลองหน้าจอเกือบทุกขนาด
หากต้องการทดสอบบนอุปกรณ์จริงแต่ไม่มีอุปกรณ์ คุณสามารถใช้ Firebase Test Lab เพื่อเข้าถึงอุปกรณ์ในศูนย์ข้อมูลของ Google
แหล่งข้อมูลเพิ่มเติม
- Material Design — การทำความเข้าใจเลย์เอาต์