ViewModel-Bereichs-APIs Teil von Android Jetpack
Der Umfang ist der Schlüssel zur effektiven Nutzung von ViewModels. Jedes ViewModel ist einem
-Objekt, das die ViewModelStoreOwner
-Schnittstelle implementiert. Es gibt
verschiedene APIs, mit denen Sie den Umfang Ihrer ViewModels einfacher verwalten können.
In diesem Dokument werden einige der wichtigsten Verfahren beschrieben.
Mit der Methode ViewModelProvider.get()
können Sie eine Instanz eines ViewModel-Objekts abrufen.
auf eine beliebige ViewModelStoreOwner
beschränkt. Für Kotlin-Nutzer gibt es
Erweiterungsfunktionen, die für die gängigsten Anwendungsfälle verfügbar sind. Kotlin (gesamt)
Implementierungen von Erweiterungsfunktionen nutzen im Hintergrund die ViewModelProvider API.
ViewModels, die auf den nächstgelegenen ViewModelStoreOwner beschränkt sind
Sie können ein ViewModel auf eine Aktivität, ein Fragment oder ein Ziel einer
Navigationsdiagramm. Die
Erweiterung viewModels()
-Funktionen, die von den Activity-, Fragment- und Navigation-Bibliotheken bereitgestellt werden, sowie der
Mit der Funktion viewModel()
in Compose können Sie eine Instanz von ViewModel abrufen.
die dem nächstgelegenen ViewModelStoreOwner
zugeordnet ist.
Aufrufe
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() }
Aufrufe
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); }
Schreiben
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, die einem beliebigen ViewModelStoreOwner zugeordnet sind
Die Funktionen ComponentActivity.viewModels()
und Fragment.viewModels()
in
Das View-System und die viewModel()
-Funktion in Compose nehmen eine optionale
ownerProducer
, mit dem Sie festlegen können,
ViewModelStoreOwner
ist die Instanz von ViewModel, der zugeordnet ist.
Im folgenden Beispiel wird gezeigt, wie Sie eine ViewModel-Instanz abrufen, die auf den
Übergeordnetes Fragment:
Aufrufe
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() } ) }
Aufrufe
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); } }
Schreiben
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() ) ) { /* ... */ }
Ein aktivitätsbezogenes ViewModel aus einem Fragment ist ein häufiger Anwendungsfall. Wann?
verwenden Sie dazu den activityViewModels()
Die Funktion der Erweiterung für Aufrufe ist verfügbar. Wenn Sie weder Views noch Kotlin verwenden,
können Sie dieselben APIs wie oben verwenden und den richtigen Inhaber übergeben.
Aufrufe
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() }
Aufrufe
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); } }
Schreiben
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() ) ) { /* ... */ }
ViewModels auf Basis der Navigationsgrafik
Navigationsdiagramme sind auch Inhaber von ViewModel-Speichern. Wenn Sie
Navigationsfragment oder
Mit der Funktion Navigation Compose können Sie
ViewModel beschränkt auf ein Navigationsdiagramm mit dem
navGraphViewModels(graphId)
Erweiterungsfunktion für Aufrufe
Aufrufe
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) } ) }
Aufrufe
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); } }
Schreiben
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) // ... } }
Wenn Sie Hilt zusätzlich zu Jetpack Navigation verwenden, können Sie
hiltNavGraphViewModels(graphId)
API wie nachfolgend beschrieben.
Aufrufe
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) }
Aufrufe
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); } }
Schreiben
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) // ... } }
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Layouts und Bindungsausdrücke
- ViewModel – Übersicht