เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์/ปรับเปลี่ยนได้ช่วยให้ผู้ใช้ได้รับประสบการณ์ที่ดีที่สุดโดยไม่คำนึงถึง ขนาดหน้าจอ ใช้เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์/ปรับเปลี่ยนได้ แอปที่อิงตามมุมมองเพื่อให้รองรับการแสดงผลทุกขนาด การวางแนว และ การกำหนดค่า รวมถึงการกำหนดค่าที่ปรับขนาดได้ เช่น multi-window โหมด
การออกแบบที่ปรับเปลี่ยนตามอุปกรณ์
ขั้นตอนแรกในการรองรับรูปแบบของอุปกรณ์ที่หลากหลายคือการสร้าง รูปแบบที่ปรับเปลี่ยนตามอุปกรณ์ในรูปแบบต่างๆ ในพื้นที่แสดงผลที่มีอยู่ กับแอปของคุณ
รูปแบบข้อจำกัด
วิธีที่ดีที่สุดในการสร้างรูปแบบที่ปรับเปลี่ยนตามอุปกรณ์คือการใช้
ConstraintLayout
เป็นเค้าโครงฐานสำหรับ UI ของคุณ ConstraintLayout
ช่วยให้คุณสามารถระบุ
ตำแหน่งและขนาดของแต่ละมุมมองตามความสัมพันธ์เชิงพื้นที่กับ
ในเค้าโครง มุมมองทั้งหมดสามารถย้ายและปรับขนาดได้พร้อมกัน
การเปลี่ยนแปลงพื้นที่แสดงผล
วิธีที่ง่ายที่สุดในการสร้างเค้าโครงด้วย ConstraintLayout
คือการใช้เค้าโครง
โปรแกรมตัดต่อใน Android Studio เครื่องมือแก้ไขการออกแบบช่วยให้คุณสามารถลากมุมมองใหม่ไปยัง
การจัดวาง ใช้ข้อจำกัดที่สัมพันธ์กับมุมมองหลักและมุมมองข้างเคียง และกำหนดมุมมอง
โดยไม่ต้องแก้ไข XML ด้วยตนเอง
สำหรับข้อมูลเพิ่มเติม โปรดดู สร้าง 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
ตามการแสดงผล
ความกว้างจะเปลี่ยนตามการวางแนวอุปกรณ์
TextView
จะกำหนดความกว้างเพื่อเติมพื้นที่ว่างทั้งหมด (match_parent
) และ
มีความสูงเท่ากับพื้นที่ซึ่งต้องการพื้นที่ตามความสูงของที่กั้น
ข้อความ (wrap_content
) ซึ่งทำให้มุมมองสามารถปรับให้เข้ากับการแสดงผลที่แตกต่างกัน
และปริมาณของข้อความที่แตกต่างกัน
หากคุณใช้ LinearLayout
คุณสามารถ
ยังสามารถขยายมุมมองย่อยตามเค้าโครง
น้ำหนัก ดังนั้นยอดดูตามสัดส่วน
พื้นที่ว่าง แต่การใช้น้ำหนักใน LinearLayout
ที่ฝังจะต้องมี
ให้ระบบดำเนินการผ่านเลย์เอาต์หลายแบบเพื่อกำหนดขนาดสำหรับแต่ละ
ทำให้ UI ทำงานช้าลง
ConstraintLayout
สามารถสร้างเลย์เอาต์ได้เกือบทั้งหมดด้วย
LinearLayout
โดยไม่ส่งผลต่อประสิทธิภาพ ดังนั้น ให้แปลงรายการที่ซ้อนกัน
LinearLayout
ถึง
ConstraintLayout
จากนั้น
สามารถกำหนดรูปแบบแบบถ่วงน้ำหนักที่มีข้อจำกัด
เชนธุรกิจ
การออกแบบที่ปรับอัตโนมัติ
เลย์เอาต์ของแอปควรตอบสนองต่อจอแสดงผลขนาดต่างๆ อยู่เสมอ อย่างไรก็ตาม แม้แต่เลย์เอาต์ที่ปรับเปลี่ยนตามอุปกรณ์ก็ไม่อาจมอบประสบการณ์ที่ดีที่สุดแก่ผู้ใช้ อุปกรณ์ทุกเครื่องหรือโหมดหลายหน้าต่างแสดงผล ตัวอย่างเช่น UI ที่คุณ ออกแบบมาเพื่อโทรศัพท์ อาจไม่ได้มอบประสบการณ์การใช้งานที่ดีที่สุดแก่ผู้ใช้ แท็บเล็ต การออกแบบแบบปรับอัตโนมัติให้เลย์เอาต์อื่นๆ ที่เพิ่มประสิทธิภาพสำหรับ ขนาดที่จะแสดง
SlidingPaneLayout สำหรับ UI รายละเอียดรายการ
UI ของรายละเอียดรายการมักจะให้ประสบการณ์การใช้งานที่แตกต่างแก่ผู้ใช้ หน้าจอขนาดต่างๆ กัน ในหน้าจอขนาดใหญ่ ระบบจะแสดงรายการและแผงรายละเอียด แสดงคู่กัน เมื่อเลือกรายการย่อยในลิสต์ ข้อมูลสินค้าจะเป็น ที่แสดงในแผงรายละเอียดโดยไม่เปลี่ยน UI - 2 ช่องนั้นยังคงอยู่ แสดงคู่กัน แต่ในหน้าจอขนาดเล็ก แผง 2 ช่องจะแสดงแยกกัน จะใช้พื้นที่แสดงผลทั้งหมด เมื่อรายการในแผงรายการ ที่เลือกไว้ แผงรายละเอียด (ที่มีข้อมูลของรายการที่เลือก) จะแทนที่ ในแผงรายการ การนำทาง "กลับ" จะแทนที่แผงรายละเอียดด้วยรายการ
SlidingPaneLayout
จะจัดการตรรกะในการพิจารณาว่าประสบการณ์ของผู้ใช้แบบใดใน 2 แบบ
เหมาะสมกับขนาดหน้าต่างปัจจุบัน:
<?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 เสมอเพราะไม่มีน้ำหนัก
แต่แผงรายละเอียดจะแสดงเต็มพื้นที่แนวนอนเกิน 580 dp เสมอ
ของการตั้งค่าlayout_weight
ของมุมมอง
ทรัพยากรเลย์เอาต์อื่นๆ
หากต้องการปรับการออกแบบ UI ให้เข้ากับขนาดการแสดงผลที่หลากหลาย ให้ใช้เลย์เอาต์อื่น ระบุโดยทรัพยากร คำขยาย
คุณจัดเตรียมเลย์เอาต์สำหรับหน้าจอที่ปรับเปลี่ยนตามอุปกรณ์ได้โดยสร้างเลย์เอาต์เพิ่มเติม
ไดเรกทอรี res/layout/
รายการในซอร์สโค้ดของแอป สร้างไดเรกทอรีสำหรับแต่ละรายการ
การกำหนดค่าหน้าจอที่จำเป็นต้องใช้การจัดวางแบบอื่น จากนั้นเพิ่มหน้าจอต่อท้าย
ตัวระบุการกำหนดค่าเป็นชื่อไดเรกทอรี layout
(เช่น
layout-w600dp
สำหรับหน้าจอที่มีความกว้าง 600dp)
ตัวระบุการกำหนดค่าจะแสดงพื้นที่แสดงผลที่มองเห็นได้สำหรับ 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 หน้าจอแต่ละแบบแตกต่างกันอย่างไร ความกว้างจะสอดคล้องกับขนาดและการวางแนวหน้าจอที่แตกต่างกัน
ค่าสำหรับตัวระบุความกว้างน้อยที่สุดคือ 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
สำหรับหน้าจอที่มีเวลา
ความสูงหน้าจออย่างน้อย 600dp
ตัวระบุการวางแนว
แม้ว่าคุณอาจสามารถรองรับรูปแบบขนาดทั้งหมดได้โดยใช้ โดยใช้ชุดค่าผสมของความกว้างที่เล็กที่สุดและความกว้างที่ใช้ได้เข้าด้วยกัน ต้องการเปลี่ยนแปลงประสบการณ์ของผู้ใช้เมื่อผู้ใช้สลับโหมดแนวตั้งด้วย และแนวนอน
สำหรับการดำเนินการดังกล่าว คุณสามารถเพิ่มตัวระบุ 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
ดูข้อมูลเพิ่มเติมเกี่ยวกับตัวระบุการกำหนดค่าหน้าจอทั้งหมดได้ที่แอป ภาพรวมทรัพยากร
คลาสขนาดหน้าต่าง
คลาสขนาดหน้าต่างคือเบรกพอยท์ของวิวพอร์ตที่จะช่วยคุณสร้างการปรับขนาดได้ เลย์เอาต์ เบรกพอยท์จะระบุพื้นที่แสดงผลที่พร้อมใช้งานสำหรับแอปของคุณดังนี้ compact, medium หรือ expanded ความกว้างและความสูงจะระบุแยกกัน เพื่อให้แอปมีคลาสขนาดหน้าต่างสำหรับความกว้าง และคลาสขนาดหน้าต่างสำหรับ และความสูง
หากต้องการใช้เลย์เอาต์แบบปรับอัตโนมัติแบบเป็นโปรแกรม ให้ทำดังนี้
- สร้างทรัพยากรเลย์เอาต์โดยอิงตามเบรกพอยท์คลาสของขนาดหน้าต่าง
- คำนวณคลาสขนาดหน้าต่างความกว้างและความสูงของแอปโดยใช้
WindowSizeClass#compute()
จาก Jetpack WindowManager คลัง - เพิ่มทรัพยากรเลย์เอาต์สำหรับคลาสขนาดหน้าต่างปัจจุบันให้สูงเกินจริง
ดูข้อมูลเพิ่มเติมได้ที่ขนาดหน้าต่าง ชั้นเรียน
คอมโพเนนต์ UI แบบแยกส่วนโดยใช้ Fragment
เมื่อออกแบบแอปสำหรับจอแสดงผลหลายขนาด ให้ใช้ Fragment เพื่อดึงข้อมูล ตรรกะ UI เป็นคอมโพเนนต์แยกกัน เพื่อให้แน่ใจว่าคุณไม่ต้องใช้ ทำซ้ำลักษณะการทำงานของ UI ในกิจกรรมต่างๆ จากนั้นคุณจะสามารถรวมส่วนย่อยเพื่อ สร้างเค้าโครงแบบหลายหน้าต่างบนหน้าจอขนาดใหญ่ หรือจะวางส่วนย่อยใน แยกกิจกรรมบนหน้าจอขนาดเล็ก
ตัวอย่างเช่น รูปแบบรายละเอียดรายการ (โปรดดู SlidingPaneLayout ด้านบน) สามารถนำไปใช้ได้ด้วยแท็ก ส่วนย่อยที่มีรายการและอีกส่วนหนึ่งที่มีรายการในลิสต์ รายละเอียด ในหน้าจอขนาดใหญ่ ชิ้นส่วนอาจแสดงคู่กัน ในวันที่ หน้าจอขนาดเล็ก แยกกัน และเต็มหน้าจอ
ดูข้อมูลเพิ่มเติมได้ในภาพรวมส่วนย่อย
การฝังกิจกรรม
หากแอปประกอบด้วยหลายกิจกรรม การฝังกิจกรรมจะช่วยให้คุณทำสิ่งต่อไปนี้ได้ สร้าง UI แบบปรับอัตโนมัติได้ง่ายๆ
การฝังกิจกรรมจะแสดงกิจกรรมหลายรายการ หรืออินสแตนซ์หลายรายการ กิจกรรมเดียวกันพร้อมกันในหน้าต่างงานของแอปพลิเคชัน ในหน้าจอขนาดใหญ่ กิจกรรมจะแสดงคู่กัน บนหน้าจอขนาดเล็ก แสดง 1 จอซ้อนกันที่ด้านบน ของอีกส่วนหนึ่ง
คุณกำหนดวิธีแสดงกิจกรรมของแอปได้โดยการสร้าง XML ซึ่งระบบใช้กำหนดค่าที่เหมาะสม งานนำเสนอตามขนาดการแสดงผล อีกทางเลือกหนึ่งคือ คุณสามารถทำให้ Jetpack WindowManager API
การฝังกิจกรรมรองรับการเปลี่ยนการวางแนวอุปกรณ์และอุปกรณ์แบบพับได้ การซ้อนหรือแยกกิจกรรมขณะที่อุปกรณ์หมุนหรือพับและกางออก
ดูข้อมูลเพิ่มเติมได้ที่กิจกรรม การฝัง
ขนาดหน้าจอและสัดส่วนภาพ
ทดสอบแอปกับหน้าจอขนาดและสัดส่วนภาพต่างๆ เพื่อให้มั่นใจว่า UI ปรับสัดส่วนได้ถูกต้อง
Android 10 (API ระดับ 29) ขึ้นไปรองรับสัดส่วนภาพที่หลากหลาย รูปแบบของอุปกรณ์แบบพับได้อาจแตกต่างกันตั้งแต่หน้าจอสูงและแคบ เช่น 21:9 เมื่อ เมื่อกางออก ให้เป็นสัดส่วนภาพรูปสี่เหลี่ยมจัตุรัส 1:1 เมื่อกางออก
ทดสอบแอปเพื่อให้ใช้งานร่วมกันได้กับอุปกรณ์จำนวนมากที่สุด สัดส่วนภาพหน้าจอต่อไปนี้ให้มากที่สุด
หากไม่มีสิทธิ์เข้าถึงอุปกรณ์สำหรับหน้าจอทุกขนาดที่คุณต้องการ ในการทดสอบ คุณสามารถใช้โปรแกรมจำลอง Android เพื่อจำลอง หน้าจอเกือบทุกขนาด
หากต้องการทดสอบบนอุปกรณ์จริงแต่ไม่มีอุปกรณ์ คุณสามารถใช้ Firebase Test Lab เพื่อเข้าถึง อุปกรณ์ในศูนย์ข้อมูลของ Google
แหล่งข้อมูลเพิ่มเติม
- ดีไซน์ Material — การทำความเข้าใจเกี่ยวกับเลย์เอาต์