ViewModel スコープ用 API(View) Android Jetpack の一部。
スコープは、ViewModel を効果的に使用するうえで重要です。各 ViewModel は、
オブジェクトをスコープとしています。ViewModelStoreOwnerViewModel のスコープをより簡単に管理できる API がいくつかあります。
ViewModelProvider.get() メソッドを使用すると、任意の ViewModelStoreOwner をスコープとする ViewModel のインスタンスを取得できます。Kotlin ユーザーには、最も一般的なユースケースで使用できるさまざまな拡張関数があります。すべての Kotlin 拡張関数の実装では、内部で ViewModelProvider API が使用されます。
最も近い ViewModelStoreOwner をスコープとする ViewModel
ViewModel をアクティビティ、フラグメント、またはナビゲーション グラフのデスティネーションにスコープ設定できます。アクティビティ、フラグメント、Navigation ライブラリによって提供される
viewModels()拡張
関数を使用すると、最も近い ViewModelStoreOwner をスコープとする ViewModel
のインスタンスを取得できます。
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() }
View
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); }
任意の ViewModelStoreOwner をスコープとする ViewModel
ComponentActivity.viewModels() 関数と Fragment.viewModels() 関数は、View システムで、ViewModel のインスタンスがどの ViewModelStoreOwner にスコープ設定されるかを指定するオプションの ownerProducer パラメータを取ります。次のサンプルは、親フラグメントをスコープとする ViewModel のインスタンスを取得する方法を示しています。
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() } ) }
View
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); } }
フラグメントからアクティビティをスコープとする ViewModel を取得することは、一般的なユースケースです。その場合は、
Views 拡張関数を使用できます。activityViewModels()View と Kotlin を使用しない場合は、上記と同じ API を、適切なオーナーを渡すことで使用できます。
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() }
View
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); } }
ナビゲーション グラフをスコープとする ViewModel
ナビゲーション グラフも ViewModel のストアオーナーです。Navigation Fragment を使用している場合は、
ナビゲーション グラフをスコープとする
ViewModel のインスタンスを
navGraphViewModels(graphId)
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) } ) }
View
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); } }
Jetpack Navigation に加えて Hilt を使用している場合は、次のように
hiltNavGraphViewModels(graphId)
API を使用できます。
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) }
View
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); } }
あなたへのおすすめ
- 注: JavaScript がオフになっている場合はリンクテキストが表示されます
- レイアウトとバインディング式
- ViewModel の概要