API-интерфейсы ViewModel Scoping . Часть Android Jetpack .
Область видимости является ключом к эффективному использованию ViewModels. Каждая ViewModel ограничена объектом, реализующим интерфейс ViewModelStoreOwner
. Существует несколько API, которые позволяют вам более легко управлять областью ваших моделей представления. В этом документе описаны некоторые ключевые методы, которые вам следует знать.
Метод ViewModelProvider.get()
позволяет получить экземпляр ViewModel, ограниченный любым ViewModelStoreOwner
. Для пользователей Kotlin доступны различные функции расширения для наиболее распространенных случаев использования. Все реализации функций расширения Kotlin используют API ViewModelProvider.
ViewModels ограничены ближайшим ViewModelStoreOwner
Вы можете ограничить ViewModel действием, фрагментом или местом назначения графа навигации. Функции расширения viewModels()
, предоставляемые библиотеками Activity, Fragment и Navigation, а также функция 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()
в системе View и функция viewModel()
в Compose принимают необязательный параметр 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 с областью действия из фрагмента является распространенным вариантом использования. При этом используйте функцию расширения представлений activityViewModels()
. Если вы не используете Views и 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() ) ) { /* ... */ }
ViewModels привязаны к графу навигации.
Навигационные графики также являются владельцами магазинов ViewModel. Если вы используете Navigation Fragment или Navigation Compose , вы можете получить экземпляр 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 Navigation, вы можете использовать API hiltNavGraphViewModels(graphId)
следующим образом.
Просмотры
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 отключен.
- Макеты и выражения привязки
- Обзор модели представления