View Model Scoping API เป็นส่วนหนึ่งของ Android Jetpack
ขอบเขตเป็นกุญแจสำคัญในการใช้ ViewModels อย่างมีประสิทธิภาพ ViewModel แต่ละรายการกำหนดขอบเขตเป็น
ที่ใช้อินเทอร์เฟซ ViewModelStoreOwner
มี
API หลายรายการที่ช่วยให้คุณจัดการขอบเขตของ ViewModels ได้ง่ายขึ้น
เอกสารนี้จะอธิบายเทคนิคหลักบางอย่างที่คุณควรทราบ
เมธอด ViewModelProvider.get()
ช่วยให้คุณรับอินสแตนซ์ของ ViewModel
กำหนดขอบเขตเป็น ViewModelStoreOwner
การใช้งาน Kotlin จะมีความแตกต่างกัน
ของส่วนขยายที่ใช้ได้กับกรณีการใช้งานทั่วไป Kotlin ทั้งหมด
การใช้ฟังก์ชันส่วนขยายจะใช้ ViewModelProvider API ขั้นสูง
ViewModels ที่กำหนดขอบเขตเป็น ViewModelStoreOwner ที่ใกล้ที่สุด
คุณสามารถกำหนดขอบเขต ViewModel ให้กับกิจกรรม ส่วนย่อย หรือปลายทางของ
กราฟการนำทาง
ส่วนขยาย viewModels()
ที่ให้บริการโดยไลบรารีกิจกรรม ส่วนย่อย และการนำทาง และ
ฟังก์ชัน viewModel()
ใน Compose ช่วยให้คุณได้รับอินสแตนซ์ของ ViewModel
กำหนดขอบเขตเป็น ViewModelStoreOwner
ที่ใกล้ที่สุด
ยอดดู
import androidx.activity.viewModels class MyActivity : AppCompatActivity() { // ViewModel API available in activity.activity-ktx // The ViewModel is scoped to `this` Activity val viewModel: MyViewModel by viewModels() } import androidx.fragment.app.viewModels class MyFragment : Fragment() { // ViewModel API available in fragment.fragment-ktx // The ViewModel is scoped to `this` Fragment val viewModel: MyViewModel by viewModels() }
ยอดดู
import androidx.lifecycle.ViewModelProvider; public class MyActivity extends AppCompatActivity { // The ViewModel is scoped to `this` Activity MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class); } public class MyFragment extends Fragment { // The ViewModel is scoped to `this` Fragment MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class); }
เขียน
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( modifier: Modifier = Modifier, // ViewModel API available in lifecycle.lifecycle-viewmodel-compose // The ViewModel is scoped to the closest ViewModelStoreOwner provided // via the LocalViewModelStoreOwner CompositionLocal. In order of proximity, // this could be the destination of a Navigation graph, the host Fragment, // or the host Activity. viewModel: MyViewModel = viewModel() ) { /* ... */ }
ViewModels ที่กำหนดขอบเขตเป็น ViewModelStoreOwner ทุกรายการ
ComponentActivity.viewModels()
และ Fragment.viewModels()
ฟังก์ชันใน
ระบบ ดู และฟังก์ชัน viewModel()
ในการเขียนจะใช้ตัวเลือก
ownerProducer
ที่คุณสามารถใช้เพื่อระบุ
ViewModelStoreOwner
มีการกำหนดขอบเขตอินสแตนซ์ของ ViewModel
ตัวอย่างต่อไปนี้แสดงวิธีรับอินสแตนซ์ของ ViewModel ขอบเขตระดับ
ส่วนย่อยระดับบนสุด:
ยอดดู
import androidx.fragment.app.viewModels class MyFragment : Fragment() { // ViewModel API available in fragment.fragment-ktx // The ViewModel is scoped to the parent of `this` Fragment val viewModel: SharedViewModel by viewModels( ownerProducer = { requireParentFragment() } ) }
ยอดดู
import androidx.lifecycle.ViewModelProvider; public class MyFragment extends Fragment { SharedViewModel viewModel; @Override public void onViewCreated(View view, Bundle savedInstanceState) { // The ViewModel is scoped to the parent of `this` Fragment viewModel = new ViewModelProvider(requireParentFragment()) .get(SharedViewModel.class); } }
เขียน
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( context: Context = LocalContext.current, // ViewModel API available in lifecycle.lifecycle-viewmodel-compose // The ViewModel is scoped to the parent of the host Fragment // where this composable function is called viewModel: SharedViewModel = viewModel( viewModelStoreOwner = (context as Fragment).requireParentFragment() ) ) { /* ... */ }
การรับ ViewModel ระดับกิจกรรมจาก Fragment เป็นกรณีการใช้งานทั่วไป วันและเวลา
โดยใช้เมนู activityViewModels()
ฟังก์ชันส่วนขยายมุมมองพร้อมใช้งาน หากไม่ได้ใช้มุมมองและ Kotlin
คุณสามารถใช้ API เดียวกับด้านบนและส่งผ่านเจ้าของที่เหมาะสม
ยอดดู
import androidx.fragment.app.activityViewModels class MyFragment : Fragment() { // ViewModel API available in fragment.fragment-ktx // The ViewModel is scoped to the host Activity val viewModel: SharedViewModel by activityViewModels() }
ยอดดู
import androidx.lifecycle.ViewModelProvider; public class MyFragment extends Fragment { SharedViewModel viewModel; @Override public void onViewCreated(View view, Bundle savedInstanceState) { // The ViewModel is scoped to the host Activity viewModel = new ViewModelProvider(requireActivity()) .get(SharedViewModel.class); } }
เขียน
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyScreen( context: Context = LocalContext.current, // ViewModel API available in lifecycle.lifecycle-viewmodel-compose // The ViewModel is scoped to the Activity of the host Fragment // where this composable function is called viewModel: SharedViewModel = viewModel( viewModelStoreOwner = (context as Fragment).requireActivity() ) ) { /* ... */ }
ดูโมเดลที่กำหนดขอบเขตเป็นกราฟการนำทาง
กราฟการนำทางยังเป็นเจ้าของร้านค้า ViewModel ด้วย หากคุณกำลังใช้
ส่วนย่อยการนำทาง หรือ
การเขียนการนำทาง คุณจะสามารถรับอินสแตนซ์ของ
ViewModel กำหนดขอบเขตเป็นกราฟการนำทางโดยใช้
navGraphViewModels(graphId)
ฟังก์ชันส่วนขยายมุมมอง
ยอดดู
import androidx.navigation.navGraphViewModels class MyFragment : Fragment() { // ViewModel API available in navigation.navigation-fragment // The ViewModel is scoped to the `nav_graph` Navigation graph val viewModel: SharedViewModel by navGraphViewModels(R.id.nav_graph) // Equivalent navGraphViewModels code using the viewModels API val viewModel: SharedViewModel by viewModels( { findNavController().getBackStackEntry(R.id.nav_graph) } ) }
ยอดดู
import androidx.lifecycle.ViewModelProvider; public class MyFragment extends Fragment { SharedViewModel viewModel; @Override public void onViewCreated(View view, Bundle savedInstanceState) { NavController navController = NavHostFragment.findNavController(this); NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph); // The ViewModel is scoped to the `nav_graph` Navigation graph viewModel = new ViewModelProvider(backStackEntry).get(SharedViewModel.class); } }
เขียน
import androidx.lifecycle.viewmodel.compose.viewModel @Composable fun MyAppNavHost() { // ... composable("myScreen") { backStackEntry -> // Retrieve the NavBackStackEntry of "parentNavigationRoute" val parentEntry = remember(backStackEntry) { navController.getBackStackEntry("parentNavigationRoute") } // Get the ViewModel scoped to the `parentNavigationRoute` Nav graph val parentViewModel: SharedViewModel = viewModel(parentEntry) // ... } }
หากคุณใช้ Hilt นอกเหนือจากการนำทางของ Jetpack คุณสามารถใช้
hiltNavGraphViewModels(graphId)
API ดังนี้
ยอดดู
import androidx.hilt.navigation.fragment.hiltNavGraphViewModels class MyFragment : Fragment() { // ViewModel API available in hilt.hilt-navigation-fragment // The ViewModel is scoped to the `nav_graph` Navigation graph // and is provided using the Hilt-generated ViewModel factory val viewModel: SharedViewModel by hiltNavGraphViewModels(R.id.nav_graph) }
ยอดดู
import androidx.hilt.navigation.HiltViewModelFactory; import androidx.lifecycle.ViewModelProvider; public class MyFragment extends Fragment { SharedViewModel viewModel; @Override public void onViewCreated(View view, Bundle savedInstanceState) { NavController navController = NavHostFragment.findNavController(this); NavBackStackEntry backStackEntry = navController.getBackStackEntry(R.id.my_graph); // The ViewModel is scoped to the `nav_graph` Navigation graph // and is provided using the Hilt-generated ViewModel factory viewModel = new ViewModelProvider( backStackEntry, HiltViewModelFactory.create(getContext(), backStackEntry) ).get(SharedViewModel.class); } }
เขียน
import androidx.hilt.navigation.compose.hiltViewModel @Composable fun MyAppNavHost() { // ... composable("myScreen") { backStackEntry -> val parentEntry = remember(backStackEntry) { navController.getBackStackEntry("parentNavigationRoute") } // ViewModel API available in hilt.hilt-navigation-compose // The ViewModel is scoped to the `parentNavigationRoute` Navigation graph // and is provided using the Hilt-generated ViewModel factory val parentViewModel: SharedViewModel = hiltViewModel(parentEntry) // ... } }
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- เลย์เอาต์และการเชื่อมโยงนิพจน์
- ดูภาพรวมของโมเดล