สถานะในแอปคือค่าใดก็ตามที่เปลี่ยนแปลงได้เมื่อเวลาผ่านไป ซึ่งเป็นคำจำกัดความที่กว้างมากและครอบคลุมทุกอย่างตั้งแต่ฐานข้อมูล Room ไปจนถึงตัวแปรในคลาส
แอป Android ทั้งหมดจะแสดงสถานะต่อผู้ใช้ ตัวอย่างสถานะในแอป Android มีดังนี้
- Snackbar ที่แสดงเมื่อไม่สามารถสร้างการเชื่อมต่อเครือข่ายได้
- บล็อกโพสต์และความคิดเห็นที่เกี่ยวข้อง
- ภาพเคลื่อนไหวแบบ Ripple บนปุ่มที่เล่นเมื่อผู้ใช้คลิก
- สติกเกอร์ที่ผู้ใช้สามารถวาดทับรูปภาพได้
Jetpack Compose ช่วยให้คุณระบุได้อย่างชัดเจนว่าจะจัดเก็บและใช้สถานะในแอป Android ที่ใดและอย่างไร คู่มือนี้จะเน้นที่ความเชื่อมโยงระหว่างสถานะกับ Composable รวมถึง API ที่ Jetpack Compose มีให้เพื่อใช้จัดการสถานะ
สถานะและการสร้าง UI
Compose เป็นแบบประกาศสิ่งที่ต้องการ ดังนั้นวิธีเดียวที่จะอัปเดต Compose ได้คือการเรียก Composable เดียวกันด้วยอาร์กิวเมนต์ใหม่ อาร์กิวเมนต์เหล่านี้แสดงถึงสถานะ UI เมื่อใดก็ตามที่สถานะได้รับการอัปเดต ระบบจะทำการ การจัดองค์ประกอบใหม่ ด้วยเหตุนี้ องค์ประกอบต่างๆ เช่น TextField จึงไม่อัปเดตโดยอัตโนมัติเหมือนกับใน View ที่ใช้ XML แบบบังคับ คุณต้องบอก Composable อย่างชัดเจนถึงสถานะใหม่เพื่อให้ Composable อัปเดตตามนั้น
@Composable private fun HelloContent() { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Hello!", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) OutlinedTextField( value = "", onValueChange = { }, label = { Text("Name") } ) } }
หากคุณเรียกใช้โค้ดนี้และพยายามป้อนข้อความ คุณจะเห็นว่าไม่มีอะไรเกิดขึ้น เนื่องจาก TextField ไม่อัปเดตตัวเอง แต่จะอัปเดตเมื่อพารามิเตอร์ value เปลี่ยนไป ซึ่งเป็นผลมาจากการทำงานของ Composition และ Recomposition ใน Compose
การสร้าง UI ครั้งแรก: การสร้าง UI โดยการเรียกใช้ Composable เป็นครั้งแรก
การจัดองค์ประกอบใหม่: การเรียกใช้ Composable อีกครั้งเพื่ออัปเดต Composition เมื่อข้อมูลเปลี่ยนแปลง
ดูข้อมูลเพิ่มเติมเกี่ยวกับการสร้าง UI ครั้งแรกและการสร้าง UI ใหม่ได้ที่ Thinking in Compose
สถานะใน Composable
ฟังก์ชัน Composable สามารถใช้ remember API เพื่อจัดเก็บออบเจ็กต์ไว้ในหน่วยความจำ ระบบจะจัดเก็บค่าที่คำนวณโดย remember ไว้ใน Composition ระหว่างการจัดองค์ประกอบครั้งแรก และจะแสดงค่าที่จัดเก็บไว้ระหว่างการจัดองค์ประกอบใหม่ คุณใช้ remember เพื่อจัดเก็บทั้งออบเจ็กต์ที่เปลี่ยนแปลงได้และเปลี่ยนแปลงไม่ได้
mutableStateOf จะสร้าง
MutableState<T> ที่สังเกตได้
ซึ่งเป็นประเภทที่สังเกตได้ซึ่งผสานรวมกับรันไทม์ของ Compose
interface MutableState<T> : State<T> {
override var value: T
}
การเปลี่ยนแปลง value จะกำหนดเวลาการสร้าง UI ใหม่ของฟังก์ชัน Composable ใดก็ตามที่อ่าน value
คุณประกาศออบเจ็กต์ MutableState ใน Composable ได้ 3 วิธี ดังนี้
val mutableState = remember { mutableStateOf(default) }var value by remember { mutableStateOf(default) }val (value, setValue) = remember { mutableStateOf(default) }
การประกาศเหล่านี้เทียบเท่ากันและมีไว้เพื่อความสะดวกในการใช้ไวยากรณ์สำหรับการใช้งานสถานะที่แตกต่างกัน คุณควรเลือกการประกาศที่สร้างโค้ดที่อ่านง่ายที่สุดใน Composable ที่คุณกำลังเขียน
ไวยากรณ์ตัวแทน by ต้องมีการนำเข้าต่อไปนี้
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
คุณสามารถใช้ค่าที่จดจำไว้เป็นพารามิเตอร์สำหรับ Composable อื่นๆ หรือแม้แต่เป็นตรรกะในคำสั่งเพื่อเปลี่ยน Composable ที่แสดง ตัวอย่างเช่น หากไม่ต้องการแสดงคำทักทายหากชื่อว่าง ให้ใช้สถานะในคำสั่ง if ดังนี้
@Composable fun HelloContent() { Column(modifier = Modifier.padding(16.dp)) { var name by remember { mutableStateOf("") } if (name.isNotEmpty()) { Text( text = "Hello, $name!", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) } OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Name") } ) } }
แม้ว่า remember จะช่วยให้คุณเก็บสถานะไว้ได้ตลอดการสร้าง UI ใหม่ แต่สถานะจะไม่ถูกเก็บไว้เมื่อมีการเปลี่ยนแปลงการกำหนดค่า คุณต้องใช้ rememberSaveable สำหรับกรณีนี้ rememberSaveable จะบันทึกค่าใดก็ตามที่บันทึกไว้ใน Bundle โดยอัตโนมัติ สำหรับค่าอื่นๆ คุณสามารถส่งออบเจ็กต์ Saver ที่กำหนดเองได้
สถานะประเภทอื่นๆ ที่รองรับ
Compose ไม่กำหนดให้คุณต้องใช้ MutableState<T> เพื่อเก็บสถานะ แต่
รองรับประเภทที่สังเกตได้อื่นๆ ก่อนที่จะอ่านประเภทที่สังเกตได้อื่นๆ ใน
Compose คุณต้องแปลงประเภทดังกล่าวเป็น State<T> เพื่อให้ Composable สร้าง UI ใหม่ได้โดยอัตโนมัติเมื่อสถานะเปลี่ยนแปลง
Compose มาพร้อมกับฟังก์ชันในการสร้าง State<T> จากประเภทที่สังเกตได้ทั่วไป
ที่ใช้ในแอป Android ก่อนที่จะใช้การผสานรวมเหล่านี้ ให้เพิ่ม
อาร์ติแฟกต์ที่เหมาะสมดังนี้
Flow:collectAsStateWithLifecycle()collectAsStateWithLifecycle()จะรวบรวมค่าจากFlowในลักษณะที่รับรู้ถึงวงจรการทำงาน ซึ่งช่วยให้แอปประหยัดทรัพยากรของแอปได้ โดยจะแสดงค่าล่าสุดที่ปล่อยออกมาจาก ComposeStateใช้ API นี้เป็นวิธีที่แนะนำในการรวบรวม Flow ในแอป Androidคุณต้องมีทรัพยากร Dependency ต่อไปนี้ในไฟล์
build.gradle(ควร เป็น 2.6.0-beta01 ขึ้นไป)
Kotlin
dependencies {
...
implementation("androidx.lifecycle:lifecycle-runtime-compose:2.10.0")
}
ดึงดูด
dependencies {
...
implementation "androidx.lifecycle:lifecycle-runtime-compose:2.10.0"
}
-
collectAsStateคล้ายกับcollectAsStateWithLifecycleเนื่องจากจะ รวบรวมค่าจากFlowและแปลงค่าดังกล่าวเป็นStateของ Compose ด้วยใช้
collectAsStateสำหรับโค้ดที่ไม่ขึ้นกับแพลตฟอร์มแทนcollectAsStateWithLifecycleซึ่งใช้ได้กับ Android เท่านั้นcollectAsStateไม่ต้องใช้ทรัพยากร Dependency เพิ่มเติม เนื่องจากมีอยู่ในcompose-runtime -
observeAsState()จะเริ่มสังเกตLiveDataนี้และแสดงค่า โดยใช้Stateคุณต้องมีทรัพยากร Dependency ต่อไปนี้ในไฟล์
build.gradle
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-livedata:1.11.4")
}
ดึงดูด
dependencies {
...
implementation "androidx.compose.runtime:runtime-livedata:1.11.4"
}
-
subscribeAsState()เป็นฟังก์ชันส่วนขยายที่แปลงสตรีมแบบโต้ตอบของ RxJava2 (เช่นSingle,Observable,Completable) เป็นStateของ Composeคุณต้องมีทรัพยากร Dependency ต่อไปนี้ในไฟล์
build.gradle
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-rxjava2:1.11.4")
}
ดึงดูด
dependencies {
...
implementation "androidx.compose.runtime:runtime-rxjava2:1.11.4"
}
-
subscribeAsState()เป็นฟังก์ชันส่วนขยายที่แปลงสตรีมแบบโต้ตอบของ RxJava3 (เช่นSingle,Observable,Completable) เป็นStateของ Composeคุณต้องมีทรัพยากร Dependency ต่อไปนี้ในไฟล์
build.gradle
Kotlin
dependencies {
...
implementation("androidx.compose.runtime:runtime-rxjava3:1.11.4")
}
ดึงดูด
dependencies {
...
implementation "androidx.compose.runtime:runtime-rxjava3:1.11.4"
}
แบบเก็บสถานะเทียบกับแบบไม่เก็บสถานะ
Composable ที่ใช้ remember เพื่อจัดเก็บออบเจ็กต์จะสร้างสถานะภายใน ซึ่งทำให้ Composable เป็นแบบ เก็บสถานะ HelloContent เป็นตัวอย่างของ Composable แบบเก็บสถานะเนื่องจากเก็บและแก้ไขสถานะ name ภายใน ซึ่งอาจมีประโยชน์ในสถานการณ์ที่ผู้เรียกไม่จำเป็นต้องควบคุมสถานะและสามารถใช้สถานะได้โดยไม่ต้องจัดการสถานะเอง อย่างไรก็ตาม Composable ที่มีสถานะภายในมักจะนำกลับมาใช้ซ้ำได้น้อยกว่าและทดสอบได้ยากกว่า
Composable แบบ ไม่เก็บสถานะ คือ Composable ที่ไม่มีสถานะ วิธีทั่วไปในการทำให้ Composable เป็นแบบไม่เก็บสถานะคือการใช้การย้ายสถานะ
เมื่อพัฒนา Composable ที่นำกลับมาใช้ซ้ำได้ คุณมักจะต้องการแสดงทั้ง Composable เวอร์ชันแบบเก็บสถานะและแบบไม่เก็บสถานะ เวอร์ชันแบบเก็บสถานะสะดวกสำหรับผู้เรียกที่ไม่สนใจสถานะ และเวอร์ชันแบบไม่เก็บสถานะจำเป็นสำหรับผู้เรียกที่ต้องควบคุมหรือย้ายสถานะ
การย้ายสถานะ
การย้ายสถานะใน Compose เป็นรูปแบบการย้ายสถานะไปยังผู้เรียกของ Composable เพื่อทำให้ Composable เป็นแบบไม่เก็บสถานะ รูปแบบทั่วไปสำหรับการย้ายสถานะใน Jetpack Compose คือการแทนที่ตัวแปรสถานะด้วยพารามิเตอร์ 2 รายการ ดังนี้
value: T: ค่าปัจจุบันที่จะแสดงonValueChange: (T) -> Unit: เหตุการณ์ที่ขอให้เปลี่ยนค่า โดยTคือค่าใหม่ที่เสนอ
อย่างไรก็ตาม คุณไม่ได้จำกัดอยู่แค่ onValueChange หากเหตุการณ์ที่เฉพาะเจาะจงมากขึ้นเหมาะกับ Composable คุณควรกำหนดเหตุการณ์เหล่านั้นโดยใช้ Lambda
สถานะที่ย้ายด้วยวิธีนี้มีคุณสมบัติที่สำคัญบางประการ ดังนี้
- แหล่งข้อมูลที่เชื่อถือได้เพียงแหล่งเดียว: การย้ายสถานะแทนการทำซ้ำจะช่วยให้มั่นใจได้ว่ามีแหล่งข้อมูลที่เชื่อถือได้เพียงแหล่งเดียว ซึ่งจะช่วยหลีกเลี่ยงข้อบกพร่อง
- ห่อหุ้ม: มีเพียง Composable แบบเก็บสถานะเท่านั้นที่แก้ไขสถานะของตนเองได้ โดยสถานะจะเป็นภายในทั้งหมด
- แชร์ได้: คุณแชร์สถานะที่ย้ายแล้วกับ Composable หลายรายการได้ หากต้องการอ่าน
nameใน Composable อื่น การย้ายสถานะจะช่วยให้คุณทำเช่นนั้นได้ - สกัดกั้นได้: ผู้เรียก Composable แบบไม่เก็บสถานะสามารถเลือกที่จะละเว้นหรือแก้ไขเหตุการณ์ก่อนที่จะเปลี่ยนสถานะ
- แยกออกจากกัน: คุณจัดเก็บสถานะสำหรับ Composable แบบไม่เก็บสถานะไว้ที่ใดก็ได้ เช่น ตอนนี้คุณสามารถย้าย
nameไปยังViewModelได้แล้ว
ในกรณีตัวอย่างนี้ คุณจะแยก name และ onValueChange ออกจาก HelloContent และย้ายขึ้นไปในโครงสร้างเป็น Composable HelloScreen ที่เรียก HelloContent
@Composable fun HelloScreen() { var name by rememberSaveable { mutableStateOf("") } HelloContent(name = name, onNameChange = { name = it }) } @Composable fun HelloContent(name: String, onNameChange: (String) -> Unit) { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Hello, $name", modifier = Modifier.padding(bottom = 8.dp), style = MaterialTheme.typography.bodyMedium ) OutlinedTextField(value = name, onValueChange = onNameChange, label = { Text("Name") }) } }
การย้ายสถานะออกจาก HelloContent จะช่วยให้คุณเข้าใจ Composable ได้ง่ายขึ้น นำกลับมาใช้ซ้ำในสถานการณ์ต่างๆ และทดสอบได้ง่ายขึ้น HelloContent จะแยกออกจากวิธีจัดเก็บสถานะ การแยกออกจากกันหมายความว่าหากคุณแก้ไขหรือแทนที่ HelloScreen คุณก็ไม่จำเป็นต้องเปลี่ยนวิธีใช้งาน HelloContent
รูปแบบที่สถานะลงไปและเหตุการณ์ขึ้นไปเรียกว่า การรับส่งข้อมูลแบบทิศทางเดียว ในกรณีนี้ สถานะจะลงจาก HelloScreen ไปยัง HelloContent และเหตุการณ์จะขึ้นจาก HelloContent ไปยัง HelloScreen การทำตามโฟลว์ข้อมูลแบบทิศทางเดียวจะช่วยให้คุณแยก Composable ที่แสดงสถานะใน UI ออกจากส่วนต่างๆ ของแอปที่จัดเก็บและเปลี่ยนสถานะได้
- ควรย้ายสถานะไปที่ระดับต่ำสุดที่ใช้ร่วมกัน ของ Composable ทั้งหมดที่ใช้สถานะ (อ่าน)
- ควรย้ายสถานะไปที่อย่างน้อย ระดับสูงสุดที่อาจมีการเปลี่ยนแปลง (เขียน)
- หากสถานะ 2 รายการเปลี่ยนแปลงเพื่อตอบสนองต่อเหตุการณ์เดียวกัน คุณควรย้ายสถานะทั้ง 2 รายการไปพร้อมกัน
คุณสามารถย้ายสถานะไปที่ระดับสูงกว่าที่กฎเหล่านี้กำหนดได้ แต่การย้ายสถานะไปที่ระดับต่ำกว่าจะทำให้การทำตามโฟลว์ข้อมูลแบบทิศทางเดียวเป็นเรื่องยากหรือเป็นไปไม่ได้
ดูข้อมูลเพิ่มเติมได้ที่หน้า ตำแหน่งที่จะย้ายสถานะ
การกู้คืนสถานะใน Compose
API rememberSaveable ทำงานคล้ายกับ remember เนื่องจากจะเก็บสถานะไว้ตลอดการสร้าง UI ใหม่ รวมถึงการสร้างกิจกรรมหรือกระบวนการ
ใหม่โดยใช้กลไกการทำงานของสถานะอินสแตนซ์ที่บันทึกไว้ เช่น เหตุการณ์นี้จะเกิดขึ้นเมื่อหมุนหน้าจอ
วิธีจัดเก็บสถานะ
ระบบจะบันทึกข้อมูลทุกประเภทที่เพิ่มลงใน Bundle โดยอัตโนมัติ หากต้องการบันทึกข้อมูลที่ไม่สามารถเพิ่มลงใน Bundle ได้ คุณมีตัวเลือกหลายอย่าง
Parcelize
โซลูชันที่ง่ายที่สุดคือการเพิ่มคำอธิบายประกอบ @Parcelize
ลงในออบเจ็กต์ ออบเจ็กต์จะกลายเป็น Parcelable และสามารถจัดกลุ่มได้ ตัวอย่างเช่น โค้ดนี้จะสร้างประเภทข้อมูล City ที่เป็น Parcelable และบันทึกข้อมูลลงในสถานะ
@Parcelize data class City(val name: String, val country: String) : Parcelable @Composable fun CityScreen() { var selectedCity = rememberSaveable { mutableStateOf(City("Madrid", "Spain")) } }
MapSaver
หาก @Parcelize ไม่เหมาะสมด้วยเหตุผลบางประการ คุณสามารถใช้ mapSaver เพื่อกำหนดกฎของคุณเองในการแปลงออบเจ็กต์เป็นชุดค่าที่ระบบบันทึกลงใน Bundle ได้
data class City(val name: String, val country: String) val CitySaver = run { val nameKey = "Name" val countryKey = "Country" mapSaver( save = { mapOf(nameKey to it.name, countryKey to it.country) }, restore = { City(it[nameKey] as String, it[countryKey] as String) } ) } @Composable fun CityScreen() { var selectedCity = rememberSaveable(stateSaver = CitySaver) { mutableStateOf(City("Madrid", "Spain")) } }
ListSaver
หากไม่ต้องการกำหนดคีย์สำหรับ Map คุณสามารถใช้ listSaver และใช้ดัชนีเป็นคีย์ได้
data class City(val name: String, val country: String) val CitySaver = listSaver<City, Any>( save = { listOf(it.name, it.country) }, restore = { City(it[0] as String, it[1] as String) } ) @Composable fun CityScreen() { var selectedCity = rememberSaveable(stateSaver = CitySaver) { mutableStateOf(City("Madrid", "Spain")) } }
ตัวเก็บสถานะใน Compose
คุณจัดการการย้ายสถานะแบบง่ายได้ในฟังก์ชัน Composable เอง อย่างไรก็ตาม หากจำนวนสถานะที่ต้องติดตามเพิ่มขึ้น หรือมีตรรกะที่ต้องดำเนินการในฟังก์ชัน Composable การมอบหมายความรับผิดชอบด้านตรรกะและสถานะให้กับคลาสอื่นๆ ซึ่งก็คือตัวเก็บสถานะ ถือเป็นแนวทางปฏิบัติที่ดี
โปรดทราบว่าในเอกสารอื่นๆ ตัวเก็บสถานะจะเรียกว่า ออบเจ็กต์สถานะที่ย้ายแล้ว ด้วย
ดูข้อมูลเพิ่มเติมได้ที่เอกสารประกอบการย้ายสถานะใน Compose หรือโดยทั่วไปคือ หน้าตัวเก็บสถานะและสถานะ UI ในคู่มือสถาปัตยกรรม
เรียกใช้การคำนวณ remember อีกครั้งเมื่อคีย์เปลี่ยนแปลง
API remember มักใช้ร่วมกับ MutableState
var name by remember { mutableStateOf("") }
ในที่นี้ การใช้ฟังก์ชัน remember จะทำให้ค่า MutableState ยังคงอยู่ตลอดการสร้าง UI ใหม่
โดยทั่วไป remember จะใช้พารามิเตอร์ Lambda calculation เมื่อเรียกใช้ remember เป็นครั้งแรก ฟังก์ชันจะเรียกใช้ Lambda calculation และจัดเก็บผลลัพธ์ ระหว่างการจัดองค์ประกอบใหม่ remember จะแสดงค่าที่จัดเก็บไว้ล่าสุด
นอกจากการแคชสถานะแล้ว คุณยังใช้ remember เพื่อจัดเก็บออบเจ็กต์หรือผลลัพธ์ของการดำเนินการใดก็ตามใน UI ที่ใช้ทรัพยากรมากในการเริ่มต้นหรือคำนวณได้ด้วย คุณอาจไม่ต้องการทำซ้ำการคำนวณนี้ในการจัดองค์ประกอบใหม่ทุกครั้ง
ตัวอย่างเช่น การสร้างออบเจ็กต์ ShaderBrush นี้เป็นการดำเนินการที่ใช้ทรัพยากรมาก
val brush = remember { ShaderBrush( BitmapShader( ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT ) ) }
remember จะจัดเก็บค่าไว้จนกว่าค่าดังกล่าวจะออกจาก UI อย่างไรก็ตาม คุณสามารถล้างค่าที่แคชไว้ได้ API remember ยังใช้พารามิเตอร์ key หรือ
keys ด้วย หากคีย์เหล่านี้มีการเปลี่ยนแปลง เมื่อฟังก์ชัน
สร้าง UI ใหม่ในครั้งถัดไป remember จะล้างแคชและเรียกใช้บล็อก Lambda calculation อีกครั้ง กลไกการทำงานนี้ช่วยให้คุณควบคุมอายุการใช้งานของออบเจ็กต์ใน UI ได้ การคำนวณจะยังคงใช้ได้จนกว่าอินพุตจะเปลี่ยนแปลง ไม่ใช่จนกว่าค่าที่จดจำไว้จะออกจาก UI
ตัวอย่างต่อไปนี้แสดงวิธีการทำงานของกลไกการทำงานนี้
ในข้อมูลโค้ดนี้ ระบบจะสร้าง ShaderBrush และใช้เป็นสีพื้นหลัง
ของ Composable Box remember จะจัดเก็บอินสแตนซ์ ShaderBrush
ไว้เนื่องจากใช้ทรัพยากรมากในการสร้างใหม่ ดังที่อธิบายไว้ก่อนหน้านี้ remember ใช้ avatarRes เป็นพารามิเตอร์ key1 ซึ่งเป็นรูปภาพพื้นหลังที่เลือก หาก avatarRes เปลี่ยนไป แปรงจะสร้าง UI ใหม่ด้วยรูปภาพใหม่และนำไปใช้กับ Box อีกครั้ง เหตุการณ์นี้อาจเกิดขึ้นเมื่อผู้ใช้เลือกรูปภาพอื่นให้เป็นพื้นหลังจากตัวเลือก
@Composable private fun BackgroundBanner( @DrawableRes avatarRes: Int, modifier: Modifier = Modifier, res: Resources = LocalContext.current.resources ) { val brush = remember(key1 = avatarRes) { ShaderBrush( BitmapShader( ImageBitmap.imageResource(res, avatarRes).asAndroidBitmap(), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT ) ) } Box( modifier = modifier.background(brush) ) { /* ... */ } }
ในข้อมูลโค้ดถัดไป ระบบจะย้ายสถานะไปยังคลาสตัวเก็บสถานะธรรมดา
MyAppState โดยจะแสดงฟังก์ชัน rememberMyAppState เพื่อเริ่มต้นอินสแตนซ์ของคลาสโดยใช้ remember การแสดงฟังก์ชันดังกล่าวเพื่อสร้างอินสแตนซ์ที่ยังคงอยู่ตลอดการสร้าง UI ใหม่เป็นรูปแบบทั่วไปใน Compose ฟังก์ชัน
rememberMyAppState จะรับ windowSizeClass ซึ่งทำหน้าที่เป็น
พารามิเตอร์ key สำหรับ remember หากพารามิเตอร์นี้เปลี่ยนแปลง แอปจะต้องสร้างคลาสตัวเก็บสถานะธรรมดาใหม่ด้วยค่าล่าสุด เหตุการณ์นี้อาจเกิดขึ้นหากผู้ใช้หมุนอุปกรณ์ เป็นต้น
@Composable private fun rememberMyAppState( windowSizeClass: WindowSizeClass ): MyAppState { return remember(windowSizeClass) { MyAppState(windowSizeClass) } } @Stable class MyAppState( private val windowSizeClass: WindowSizeClass ) { /* ... */ }
Compose ใช้การใช้งาน equals ของคลาสเพื่อพิจารณาว่าคีย์มีการ เปลี่ยนแปลงหรือไม่ และล้างค่าที่จัดเก็บไว้
จัดเก็บสถานะด้วยคีย์นอกเหนือจากการจัดองค์ประกอบใหม่
API rememberSaveable เป็น Wrapper สำหรับ remember ที่จัดเก็บ
ข้อมูลใน Bundle ได้ API นี้ช่วยให้สถานะยังคงอยู่ไม่เพียงแต่ตลอดการสร้าง UI ใหม่เท่านั้น แต่ยังรวมถึงการสร้างกิจกรรมใหม่และการสิ้นสุดกระบวนการที่ระบบเริ่มด้วย
rememberSaveable จะรับพารามิเตอร์ input เพื่อวัตถุประสงค์เดียวกับที่
remember รับ keys ระบบจะล้างแคชเมื่ออินพุตใดก็ตามมีการเปลี่ยนแปลง เมื่อฟังก์ชันสร้าง UI ใหม่ในครั้งถัดไป rememberSaveable จะเรียกใช้บล็อก Lambda calculation อีกครั้ง
ในตัวอย่างต่อไปนี้ rememberSaveable จะจัดเก็บ userTypedQuery ไว้จนกว่า typedQuery จะเปลี่ยนแปลง
var userTypedQuery by rememberSaveable(typedQuery, stateSaver = TextFieldValue.Saver) { mutableStateOf( TextFieldValue(text = typedQuery, selection = TextRange(typedQuery.length)) ) }
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับสถานะและ Jetpack Compose ได้จากแหล่งข้อมูลเพิ่มเติมต่อไปนี้
ตัวอย่าง
Codelab
วิดีโอ
บล็อก
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- การออกแบบสถาปัตยกรรม UI ของ Compose
- บันทึกสถานะ UI ใน Compose
- ผลข้างเคียงใน Compose