API Cakupan ViewModel Bagian dari Android Jetpack.
Cakupan adalah kunci untuk menggunakan ViewModel secara efektif. Setiap ViewModel dicakup ke
objek yang menerapkan antarmuka ViewModelStoreOwner
. Ada beberapa
API yang memungkinkan Anda mengelola cakupan ViewModel dengan lebih mudah.
Dokumen ini menguraikan beberapa teknik utama yang harus Anda ketahui.
Metode ViewModelProvider.get()
memungkinkan Anda mendapatkan instance ViewModel
yang dicakupkan ke ViewModelStoreOwner
apa pun. Untuk pengguna Kotlin, terdapat berbagai fungsi ekstensi yang tersedia untuk kasus penggunaan paling umum. Semua
penerapan fungsi ekstensi Kotlin menggunakan ViewModelProvider API di balik layar.
ViewModel yang dicakupkan ke ViewModelStoreOwner terdekat
Anda dapat menentukan cakupan ViewModel ke Activity, Fragment, atau tujuan
grafik Navigation. Fungsi
ekstensi viewModels()
yang disediakan oleh library Activity, Fragment, dan Navigation, serta
fungsi viewModel()
di Compose memungkinkan Anda mendapatkan instance ViewModel
yang dibatasi ke ViewModelStoreOwner
terdekat.
View
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() }
Penayangan
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); }
Compose
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() ) { /* ... */ }
ViewModel yang dicakupkan ke ViewModelStoreOwner apa pun
Fungsi ComponentActivity.viewModels()
danFragment.viewModels()
di sistem View
dan fungsi viewModel()
di Compose mengambil
parameter ownerProducer
opsional yang dapat Anda gunakan untuk menentukan
ViewModelStoreOwner
tempat instance ViewModel dicakupkan.
Contoh berikut menunjukkan cara mendapatkan instance ViewModel yang dicakupkan ke
fragmen induk:
View
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() } ) }
Penayangan
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); } }
Compose
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() ) ) { /* ... */ }
Mendapatkan ViewModel Cakupan Activity dari Fragment adalah kasus penggunaan umum. Kapan
melakukannya, gunakan activityViewModels()
Fungsi ekstensi View tersedia. Jika tidak menggunakan View dan Kotlin,
Anda dapat menggunakan API yang sama seperti di atas dan dengan meneruskan pemilik yang tepat.
View
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() }
Penayangan
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); } }
Compose
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 yang dicakupkan ke grafik Navigation
Grafik Navigation juga merupakan pemilik penyimpanan ViewModel. Jika menggunakan
Navigation Fragment atau
Navigation Compose, Anda bisa mendapatkan instance
ViewModel yang dicakupkan ke grafik Navigation dengan
navGraphViewModels(graphId)
fungsi ekstensi View.
View
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) } ) }
Penayangan
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); } }
Compose
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) // ... } }
Jika menggunakan Hilt sebagai tambahan Jetpack Navigation, Anda dapat menggunakan
hiltNavGraphViewModels(graphId)
API sebagai berikut.
View
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) }
Penayangan
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); } }
Compose
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) // ... } }
Direkomendasikan untuk Anda
- Catatan: teks link ditampilkan saat JavaScript nonaktif
- Tata letak dan ekspresi binding
- Ringkasan ViewModel