การกำหนดค่าอุปกรณ์บางอย่างอาจเปลี่ยนแปลงได้ขณะที่แอปทำงานอยู่ ซึ่งรวมถึงแต่ไม่จำกัดเพียง
- ขนาดการแสดงผลของแอป
- การวางแนวหน้าจอ
- ขนาดและน้ำหนักแบบอักษร
- ภาษา
- โหมดมืดเทียบกับโหมดสว่าง
- ความพร้อมใช้งานของแป้นพิมพ์
การเปลี่ยนแปลงการกำหนดค่าส่วนใหญ่เหล่านี้เกิดขึ้นเนื่องจากการโต้ตอบของผู้ใช้บางอย่าง เช่น การหมุนหรือพับอุปกรณ์จะเปลี่ยนปริมาณพื้นที่หน้าจอที่แอปของคุณใช้ได้ ในทำนองเดียวกัน การเปลี่ยนการตั้งค่าอุปกรณ์ เช่น ขนาดตัวอักษร ภาษา หรือธีมที่ต้องการ จะเปลี่ยนค่าที่เกี่ยวข้องในออบเจ็กต์ Configuration
โดยปกติแล้ว พารามิเตอร์เหล่านี้มักต้องมีการเปลี่ยนแปลง UI ของแอปพลิเคชันมากพอ
ที่แพลตฟอร์ม Android จะมีกลไกที่สร้างขึ้นโดยเฉพาะเมื่อมีการเปลี่ยนแปลง
กลไกนี้คือActivityการสร้างใหม่
การสร้างกิจกรรมใหม่
ระบบจะสร้าง Activity ขึ้นใหม่เมื่อมีการเปลี่ยนแปลงการกำหนดค่า หากต้องการทำเช่นนี้ ระบบจะเรียกใช้ onDestroy และทำลายอินสแตนซ์ Activity
ที่มีอยู่ จากนั้นจะสร้างอินสแตนซ์ใหม่โดยใช้ onCreate และระบบจะเริ่มต้นอินสแตนซ์ Activity ใหม่นี้ด้วยการกำหนดค่าใหม่ที่อัปเดตแล้ว ซึ่ง
ยังหมายความว่าระบบจะสร้าง UI ใหม่ด้วยการกำหนดค่าใหม่ด้วย
โดยปกติแล้ว Activity จะทำหน้าที่เป็นโฮสต์สำหรับ Composable เมื่อมีการสร้าง Activity ใหม่ Compose จะสร้าง UI ใหม่โดยใช้ค่าการกำหนดค่าใหม่ด้วย
ลักษณะการทำงานของการสร้างใหม่ช่วยให้แอปพลิเคชันปรับตัวให้เข้ากับการกำหนดค่าใหม่ได้โดย โหลดแอปพลิเคชันซ้ำโดยอัตโนมัติด้วยทรัพยากรทางเลือกที่ตรงกับ การกำหนดค่าอุปกรณ์ใหม่
ตัวอย่างการพักผ่อนหย่อนใจ
ลองพิจารณา Composable ที่แสดงชื่อแบบคงที่โดยใช้ทรัพยากรสตริง
// In the res/values/strings.xml file // <string name="compose">Jetpack Compose</string> // In your Compose code Text( text = stringResource(R.string.compose) )
เมื่อสร้าง Activity แล้ว Text Composable จะอ่านการกำหนดค่าปัจจุบัน (เช่น ภาษา) และแสดงผลทรัพยากรสตริงที่เหมาะสม
หากมีการเปลี่ยนภาษา ระบบจะสร้างกิจกรรมขึ้นใหม่ เมื่อเกิดเหตุการณ์เช่นนี้ Compose จะสร้าง UI ขึ้นมาใหม่ เนื่องจาก stringResource อ่านจากการกําหนดค่าปัจจุบัน
ชื่อจึงอัปเดตเป็นค่าที่แปลอย่างถูกต้องโดยอัตโนมัติ
การสร้างใหม่นี้ยังล้างสถานะที่เก็บไว้เป็นฟิลด์ใน
Activity ด้วย
หากต้องการรักษาสถานะ UI ไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า ให้ใช้รูปแบบการจัดการสถานะที่แนะนำ ใช้ ViewModel สำหรับข้อมูลและตรรกะทางธุรกิจ และใช้
rememberSaveable สำหรับสถานะระดับ UI กลไกเหล่านี้ช่วยให้สถานะของคุณยังคงอยู่เมื่อมีการสร้าง Activity ใหม่ ขณะที่ UI จะอัปเดตเพื่อแสดงการกำหนดค่าใหม่
ดูข้อมูลเพิ่มเติมเกี่ยวกับการบันทึกสถานะใน Compose ได้ที่ บันทึกสถานะ UI ใน Compose
Activity
ความคาดหวังของผู้ใช้
ผู้ใช้แอปคาดหวังให้ระบบเก็บสถานะไว้ หากผู้ใช้กำลังกรอกแบบฟอร์มและเปิดแอปอื่นในโหมดหลายหน้าต่างเพื่ออ้างอิงข้อมูล การที่ผู้ใช้กลับไปที่แบบฟอร์มที่ล้างแล้วหรือไปยังที่อื่นในแอปทั้งหมดถือเป็นประสบการณ์ที่ไม่ดีสำหรับผู้ใช้ ในฐานะนักพัฒนาแอป คุณต้องมอบประสบการณ์การใช้งานที่สอดคล้องกันแก่ผู้ใช้ ผ่านการเปลี่ยนแปลงการกำหนดค่าและการสร้างกิจกรรมใหม่
หากต้องการยืนยันว่าแอปพลิเคชันของคุณยังคงรักษาสถานะไว้หรือไม่ คุณสามารถดำเนินการ ที่ทำให้เกิดการเปลี่ยนแปลงการกำหนดค่าทั้งในขณะที่แอปอยู่เบื้องหน้า และขณะที่แอปอยู่เบื้องหลัง การทำงานดังกล่าว ได้แก่:
- การหมุนอุปกรณ์
- เข้าสู่โหมดหลายหน้าต่าง
- การปรับขนาดแอปพลิเคชันขณะอยู่ในโหมดหลายหน้าต่างหรือหน้าต่างอิสระ
- การพับอุปกรณ์ที่พับได้ซึ่งมีหลายจอแสดงผล
- การเปลี่ยนธีมของระบบ เช่น โหมดมืดเทียบกับโหมดสว่าง
- การเปลี่ยนขนาดแบบอักษร
- การเปลี่ยนภาษาของระบบหรือแอป
- การเชื่อมต่อหรือยกเลิกการเชื่อมต่อแป้นพิมพ์ฮาร์ดแวร์
- การเชื่อมต่อหรือยกเลิกการเชื่อมต่อแท่นวาง
คุณใช้แนวทางต่างๆ เพื่อรักษาสถานะที่เกี่ยวข้องผ่านการ
Activityสร้างใหม่ได้ โดยการเลือกใช้จะขึ้นอยู่กับประเภทสถานะที่ต้องการ
เก็บรักษา
- การคงอยู่ของข้อมูลในเครื่องเพื่อจัดการการสิ้นสุดการประมวลผลสำหรับข้อมูลที่ซับซ้อนหรือมีขนาดใหญ่
พื้นที่เก็บข้อมูลในเครื่องแบบถาวรรวมถึงฐานข้อมูลหรือ
DataStore - ออบเจ็กต์ที่เก็บไว้ เช่น อินสแตนซ์
ViewModelเพื่อจัดการสถานะที่เกี่ยวข้องกับ UI ในหน่วยความจำขณะที่ผู้ใช้ใช้งานแอปอยู่ rememberSaveableเพื่อรักษาสถานะ UI ชั่วคราวเมื่อมีการเปลี่ยนแปลงการกำหนดค่าและการสิ้นสุดการประมวลผลที่ระบบเริ่มต้น ซึ่งเหมาะสำหรับสถานะ ที่ขึ้นอยู่กับข้อมูลจากผู้ใช้ ตำแหน่งการเลื่อน หรือการนำทาง แต่ไม่ได้อยู่ในViewModel
หากต้องการอ่านข้อมูลโดยละเอียดเกี่ยวกับ API สำหรับแต่ละรายการเหล่านี้ และเมื่อใดที่ควรใช้แต่ละรายการ โปรดดูบันทึกสถานะ UI
จำกัดการสร้างกิจกรรมใหม่
คุณป้องกันไม่ให้ระบบสร้างกิจกรรมขึ้นมาใหม่โดยอัตโนมัติสำหรับการเปลี่ยนแปลงการกำหนดค่าบางอย่างได้ ในแอปที่ใช้ Compose อย่างเดียวในปัจจุบัน UI จะได้รับการจัดองค์ประกอบใหม่ไม่ว่าจะด้วยวิธีใดก็ตาม แต่เราขอแนะนําให้จัดการการเปลี่ยนแปลงการกําหนดค่าโดยตรง
โดยค่าเริ่มต้น การเปลี่ยนแปลงการกำหนดค่าจะบังคับให้ระบบทำลายและสร้าง Activity ขึ้นมาใหม่
รวมถึง UI และออบเจ็กต์ใดๆ ที่ได้มาจาก Activity หากคุณประกาศว่ากิจกรรมของคุณจัดการการเปลี่ยนแปลงการกำหนดค่าด้วยตัวเอง ระบบจะป้องกันไม่ให้เกิดเหตุการณ์นี้ แต่จะมีเพียงออบเจ็กต์ Configuration เท่านั้นที่อัปเดต และ
Compose จะสร้าง UI ใหม่ด้วยค่าใหม่
การจัดการการเปลี่ยนแปลงการกำหนดค่าใน Compose โดยตรงมีประโยชน์หลายประการ ดังนี้
- ประสิทธิภาพที่ดียิ่งขึ้น: การจัดองค์ประกอบ UI ใหม่มีค่าใช้จ่ายน้อยกว่าวงจรการสร้าง Activity ใหม่ทั้งหมด โดยเฉพาะอย่างยิ่งสำหรับการเปลี่ยนแปลงเล็กๆ น้อยๆ
- ภาพเคลื่อนไหวที่ลื่นไหล: การหลีกเลี่ยงการรีสตาร์ทกิจกรรมช่วยให้คุณเรียกใช้ภาพเคลื่อนไหวอย่างต่อเนื่องเมื่อมีการเปลี่ยนแปลงการกำหนดค่า เช่น การเปลี่ยนเลย์เอาต์อย่างราบรื่นระหว่างการหมุนอุปกรณ์
- การรักษาสถานะ: การเก็บอินสแตนซ์ของกิจกรรมไว้จะช่วยลดความเสี่ยงที่ สถานะ UI ชั่วคราวจะสูญหายระหว่างเหตุการณ์ต่างๆ เช่น การหมุนหน้าจอ โปรดทราบว่าคุณ ยังคงต้องจัดการการรักษาสถานะสำหรับการสิ้นสุดกระบวนการที่ระบบเริ่มต้น
หากต้องการปิดใช้การสร้างกิจกรรมใหม่สำหรับการเปลี่ยนแปลงการกำหนดค่าบางอย่าง ให้เพิ่มประเภทการกำหนดค่าลงใน android:configChanges ในรายการ <activity> ในไฟล์ AndroidManifest.xml ค่าที่เป็นไปได้
จะปรากฏในเอกสารประกอบสำหรับแอตทริบิวต์ android:configChanges
โค้ด Manifest ต่อไปนี้จะปิดใช้Activityการสร้างใหม่สำหรับMyActivity เมื่อ
การวางแนวหน้าจอและความพร้อมใช้งานของแป้นพิมพ์เปลี่ยนแปลง
<activity
android:name=".MyActivity"
android:configChanges="orientation|screenSize|screenLayout|keyboardHidden"
android:label="@string/app_name">
ตอบสนองต่อการเปลี่ยนแปลงการกำหนดค่า
Jetpack Compose ช่วยให้แอปตอบสนองต่อการเปลี่ยนแปลงการกำหนดค่าได้ง่ายขึ้น
อย่างไรก็ตาม หากคุณปิดใช้Activityการสร้างใหม่สำหรับการเปลี่ยนแปลงการกำหนดค่าทั้งหมด
ในกรณีที่ทำได้ แอปของคุณยังคงต้องจัดการการเปลี่ยนแปลงการกำหนดค่า
อย่างถูกต้อง
ออบเจ็กต์ Configuration พร้อมใช้งานในลำดับชั้น Compose UI โดยมีองค์ประกอบ LocalConfiguration อยู่ในองค์ประกอบเฉพาะที่ เมื่อใดก็ตามที่ค่าเปลี่ยน ฟังก์ชันที่ประกอบกันได้ซึ่งอ่านจาก LocalConfiguration.current จะทำการเขียนใหม่ ดูข้อมูลเกี่ยวกับวิธีการทำงานของ CompositionLocal ได้ที่ข้อมูลที่กำหนดขอบเขตในเครื่อง
ด้วย CompositionLocal
ตัวอย่าง
ในตัวอย่างต่อไปนี้ Composable จะแสดงวันที่ในรูปแบบที่เฉพาะเจาะจง
Composable จะตอบสนองต่อการเปลี่ยนแปลงการกำหนดค่าภาษาของระบบโดยการเรียก ConfigurationCompat.getLocales ด้วย LocalConfiguration.current
@Composable
fun DateText(year: Int, dayOfYear: Int) {
val dateTimeFormatter = DateTimeFormatter.ofPattern(
"MMM dd",
ConfigurationCompat.getLocales(LocalConfiguration.current)[0]
)
Text(
dateTimeFormatter.format(LocalDate.ofYearDay(year, dayOfYear))
)
}
Activityโฮสติ้ง
โค้ด Compose ต้องเลือกไม่ใช้การเปลี่ยนแปลงการกำหนดค่าภาษาเพื่อหลีกเลี่ยงActivityการสร้างใหม่เมื่อมีการเปลี่ยนภาษา โดยคุณต้อง
ตั้งค่า android:configChanges เป็น locale|layoutDirection
การเปลี่ยนแปลงการกำหนดค่า: แนวคิดหลักและแนวทางปฏิบัติแนะนำ
แนวคิดสำคัญที่ควรทราบเมื่อทำการเปลี่ยนแปลงการกำหนดค่ามีดังนี้
- การกำหนดค่า: การกำหนดค่าอุปกรณ์จะกำหนดวิธีที่ UI แสดงต่อผู้ใช้ เช่น ขนาดการแสดงผลแอป ภาษา หรือธีมของระบบ ใน Compose คุณ
เข้าถึงค่าการกำหนดค่าได้โดยใช้
LocalConfiguration - การเปลี่ยนแปลงการกำหนดค่า: การกำหนดค่าจะเปลี่ยนแปลงผ่านการโต้ตอบของผู้ใช้ เช่น ผู้ใช้อาจเปลี่ยนการตั้งค่าอุปกรณ์หรือวิธีโต้ตอบกับอุปกรณ์ โดยตรง คุณไม่สามารถป้องกัน การเปลี่ยนแปลงการกำหนดค่าได้
Activityการสร้างใหม่: การเปลี่ยนแปลงการกำหนดค่าจะส่งผลให้เกิดActivityการสร้างใหม่โดยค่าเริ่มต้น ซึ่งเป็นกลไกในตัวเพื่อเริ่มต้นสถานะแอปอีกครั้ง สำหรับการกำหนดค่าใหม่Activityการทำลาย:Activityการสร้างใหม่ทำให้ระบบทำลายอินสแตนซ์Activityเก่าและสร้างอินสแตนซ์ใหม่แทนที่ ตอนนี้อินสแตนซ์เก่า ล้าสมัยแล้ว หลีกเลี่ยงการเก็บข้อมูลอ้างอิงถึงออบเจ็กต์ที่มีขอบเขตระดับวงจร นอกเหนือขอบเขตที่ตั้งใจไว้- สถานะ: สถานะในอินสแตนซ์
Activityเก่าจะไม่มีอยู่ในอินสแตนซ์Activityใหม่เนื่องจากเป็นอินสแตนซ์ออบเจ็กต์ที่แตกต่างกัน แทนที่จะเชื่อมโยงสถานะกับกิจกรรม ให้ใช้ API ที่แนะนําเพื่อรักษาสถานะของแอปและผู้ใช้ตามที่อธิบายไว้ในบันทึกสถานะ UI - การเลือกไม่ใช้: การเลือกไม่ใช้การสร้างกิจกรรมใหม่สําหรับการเปลี่ยนแปลงประเภทการกําหนดค่า กําหนดให้แอปของคุณอัปเดตอย่างถูกต้องเพื่อตอบสนองต่อการกําหนดค่าใหม่
โปรดปฏิบัติตามแนวทางปฏิบัติแนะนำต่อไปนี้เพื่อมอบประสบการณ์การใช้งานที่ดีให้แก่ผู้ใช้
- เตรียมพร้อมสำหรับการเปลี่ยนแปลงการกำหนดค่าบ่อยๆ: อย่าคิดว่าการเปลี่ยนแปลงการกำหนดค่าเกิดขึ้นไม่บ่อยหรือไม่มีเลย ไม่ว่าจะเป็นระดับ API, รูปแบบ หรือชุดเครื่องมือ UI เมื่อผู้ใช้ทำให้เกิดการเปลี่ยนแปลงการกำหนดค่า ผู้ใช้จะคาดหวังให้แอปอัปเดตและทำงานต่อไปอย่างถูกต้องกับการกำหนดค่าใหม่
- รักษาสถานะ: อย่าทำให้สถานะของผู้ใช้หายไปเมื่อเกิด
Activityการสร้างใหม่ รักษาสถานะตามที่อธิบายไว้ในบันทึกสถานะ UI โดยใช้ API เช่นViewModelและrememberSaveable - หลีกเลี่ยงการเลือกไม่ใช้เพื่อแก้ปัญหาอย่างรวดเร็ว: อย่าเลือกไม่ใช้
Activityการสร้างใหม่ เป็นทางลัดเพื่อหลีกเลี่ยงการสูญเสียสถานะ การเลือกไม่ใช้การสร้างกิจกรรมใหม่กำหนดให้คุณต้องทำตามสัญญาในการจัดการการเปลี่ยนแปลง และคุณอาจยังคงสูญเสียสถานะเนื่องจากActivityการสร้างใหม่จากการเปลี่ยนแปลงการกำหนดค่าอื่นๆ กระบวนการ สิ้นสุด หรือการปิดแอป การปิดใช้การสร้างActivityใหม่ทั้งหมดเป็นไปไม่ได้ เก็บรักษาสถานะตามที่อธิบายไว้ในบันทึกสถานะ UI - อย่าหลีกเลี่ยงการเปลี่ยนแปลงการกำหนดค่า: อย่าจำกัดการวางแนว
สัดส่วนภาพ หรือการปรับขนาดเพื่อหลีกเลี่ยงการเปลี่ยนแปลงการกำหนดค่าและ
Activityการสร้างใหม่ ซึ่งจะส่งผลเสียต่อผู้ใช้ที่ต้องการใช้แอปของคุณ ในวิธีที่ต้องการ
จัดการการเปลี่ยนแปลงการกำหนดค่าตามขนาด
การเปลี่ยนแปลงการกำหนดค่าตามขนาดอาจเกิดขึ้นได้ทุกเมื่อและมีแนวโน้มที่จะเกิดขึ้นมากขึ้น เมื่อแอปทำงานบนอุปกรณ์หน้าจอขนาดใหญ่ที่ผู้ใช้สามารถเข้าสู่โหมดหลายหน้าต่างได้ ผู้ใช้คาดหวังว่าแอปของคุณจะทำงานได้ดีในสภาพแวดล้อมดังกล่าว
การเปลี่ยนแปลงขนาดมี 2 ประเภทหลักๆ ได้แก่ มีนัยสำคัญและไม่มีนัยสำคัญ การเปลี่ยนแปลงขนาดที่มีนัยสำคัญคือการเปลี่ยนแปลงที่ชุดทรัพยากรสำรองที่แตกต่างกันมีผลกับการกำหนดค่าใหม่เนื่องจากความแตกต่างของขนาดหน้าจอ เช่น ความกว้าง ความสูง หรือความกว้างที่เล็กที่สุด ทรัพยากรเหล่านี้รวมถึงทรัพยากรที่แอปกำหนดเองและทรัพยากรจากไลบรารีของแอป
จำกัดการสร้างกิจกรรมใหม่สำหรับการเปลี่ยนแปลงการกำหนดค่าตามขนาด
เมื่อปิดใช้Activityการสร้างใหม่สำหรับการเปลี่ยนแปลงการกำหนดค่าตามขนาด ระบบจะไม่สร้างActivityใหม่ แต่จะรับการเรียกไปยัง Activity.onConfigurationChanged คอมโพสใดๆ ที่อ่าน LocalConfiguration.current จะคอมโพสใหม่โดยอัตโนมัติเพื่อแสดงขนาดใหม่
ระบบจะปิดใช้การสร้าง Activity ใหม่สำหรับการเปลี่ยนแปลงการกำหนดค่าตามขนาดเมื่อคุณมี android:configChanges="screenSize|smallestScreenSize|orientation|screenLayout"
ในไฟล์ Manifest
แหล่งข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการจัดการการเปลี่ยนแปลงการกำหนดค่าได้ที่ แหล่งข้อมูลเพิ่มเติมต่อไปนี้