Single Activity with MVVM

Single Activity with MVVM

A374f41eab3f73c50d8bab0652cb207a?s=128

TakuSemba

March 26, 2019
Tweet

Transcript

  1. 7.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph"> <fragment android:id="@+id/firstFragment"

    android:name=“your.package.FirstFragment” /> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment”/> </navigation> <navigation <fragment android:id="@+id/firstFragment" android:name=“your.package.FirstFragment" /> <fragment android:id="@+id/secondFragment" android:name="your.package.SecondFragment"/> </navigation>
  2. 8.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment

    android:id="@+id/firstFragment" android:name=“your.package.FirstFragment” /> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment”/> </navigation> <navigation app:startDestination="@id/firstFragment"> <fragment android:id="@+id/firstFragment" android:name=“your.package.FirstFragment" /> <fragment android:id="@+id/secondFragment" android:name="your.package.SecondFragment"/> </navigation>
  3. 9.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment

    android:id="@+id/firstFragment" android:name=“your.package.FirstFragment"> <action android:id="@+id/to_secondFragment" app:destination="@id/secondFragment"/> </fragment> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment"/> </navigation> <fragment android:id="@+id/firstFragment" android:name="your.package.FirstFragment"> <action android:id="@+id/to_secondFragment" app:destination="@id/secondFragment"/> </fragment>
  4. 10.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment

    android:id="@+id/firstFragment" android:name="your.package.FirstFragment"> <action android:id="@+id/to_secondFragment" app:destination="@id/secondFragment"/> </fragment> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment"> <argument android:name="userId" app:argType="string"/> </fragment> </navigation> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment"> <argument android:name="userId" app:argType="string"/> </fragment>
  5. 11.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/nav_graph" app:startDestination="@id/firstFragment"> <fragment

    android:id="@+id/firstFragment" android:name="your.package.FirstFragment"> <action android:id="@+id/to_secondFragment" app:destination="@id/secondFragment"/> </fragment> <fragment android:id="@+id/secondFragment" android:name=“your.package.SecondFragment"> <argument android:name="userId" app:argType="string"/> </fragment> </navigation>
  6. 12.
  7. 15.

    val navController = findNavController(R.id.host_fragment) // find from activity val navController

    = findNavController() // find from fragment val navController = findNavController() // find from view
  8. 16.

    val navController = findNavController(R.id.host_fragment) // find from activity val navController

    = findNavController() // find from fragment val navController = findNavController() // find from view val args = bundleOf(SecondFragment.KEY_USER_ID to userId) navController.navigate(R.id.toSecondFragment, args) // navigate to secondFragment.kt
  9. 17.

    val navController = findNavController(R.id.host_fragment) // find from activity val navController

    = findNavController() // find from fragment val navController = findNavController() // find from view // navigate to secondFragment.kt val directions = FirstFragmentDirections.toSecondFragment(userId) navController.navigate(directions)
  10. 18.

    val navController = findNavController(R.id.host_fragment) // find from activity val navController

    = findNavController() // find from fragment val navController = findNavController() // find from view // navigate to secondFragment.kt val directions = FirstFragmentDirections.toSecondFragment(userId) navController.navigate(directions) // get userId from arguments val args = SecondFragmentArgs.fromBundle(requireArguments()) val userId = args.userId
  11. 19.

    val navController = findNavController(R.id.host_fragment) // find from activity val navController

    = findNavController() // find from fragment val navController = findNavController() // find from view // navigate to secondFragment.kt val directions = FirstFragmentDirections.toSecondFragment(userId) navController.navigate(directions) // get userId from arguments private val args by navArgs<SecondFragmentArgs>() val userId = args.userId
  12. 23.

    <?xml version="1.0" encoding="utf-8"?> <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/nav_graph" app:startDestination="@id/launcherFragment" > <action

    android:id="@+id/action_global_ maintainanceFragment” app:destination="@id/maintainanceFragment" /> <fragment … /> <fragment … /> </navigation> // global action
  13. 26.

    Nav Options special options for navigate actions public NavOptions.Builder setPopUpTo

    (int destinationId, boolean inclusive) public NavOptions.Builder setLaunchSingleTop (boolean singleTop) …
  14. 29.

    val directions = SplashDirections.showLoginFragment() val options = NavOptions.Builder() .setPopUpTo(R.id.splashFragment, true)

    .build() navController.navigate(directions, options) // navigate with stacked fragmetns popoed up
  15. 30.

    // navigate to loginFragment val directions = SplashDirections.showLoginFragment() navController.navigate(directions) <?xml

    version="1.0" encoding="utf-8"?> <navigation> <fragment android:id="@+id/splashFragment" android:name="your.package.SplashFragment" tools:layout="@layout/fragment_splash"> <action android:id="@+id/showLoginFragment" app:destination="@id/loginFragment" app:popUpTo="@id/splashFragment" app:popUpToInclusive="true"/> </fragment> </navigation> <action app:popUpTo="@id/splashFragment" app:popUpToInclusive="true"/> // navigate with stacked fragmetns popoed up
  16. 31.

    // navigate as single-top val directions = NavGraphDirections.showBarFragment() navController.navigate(directions) val

    directionsAgain = NavGraphDirections.showBarFragment() navController.navigate(directionsAgain)
  17. 32.

    val directions = NavGraphDirections.showBarFragment() navController.navigate(directions) val directionsAgain = NavGraphDirections.showBarFragment() val

    options = NavOptions.Builder() .setLaunchSingleTop(true) .build() navController.navigate(directions, options) // navigate as single-top
  18. 33.

    // navigate to barFragment val directions = NavGraphDirections.showBarFragment() navController.navigate(directions) <?xml

    version="1.0" encoding="utf-8"?> <navigation> <fragment android:id="@+id/splashFragment" android:name="your.package.SplashFragment" tools:layout="@layout/fragment_splash"> <action android:id="@+id/showLoginFragment" app:destination="@id/loginFragment" app:launchSingleTop="true"/> </fragment> </navigation> <action app:launchSingleTop="true"/> // navigate as single-top
  19. 36.

    navController.popBackStack() // navigate back // observe data override fun onViewCreated(view:

    View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.user.observe(this) { user -> textView.text = user.name } }
  20. 37.

    navController.popBackStack() // navigate back // observe data override fun onViewCreated(view:

    View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.user.observe(this) { user -> textView.text = user.name } } observe(this) { user -> }
  21. 38.

    navController.popBackStack() // navigate back // observe data override fun onViewCreated(view:

    View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.user.observe(this) { user -> textView.text = user.name } } observe(this) { user -> } override fun onDestroy() { super.onDestroy() // not called yet }
  22. 39.

    navController.popBackStack() // navigate back // observe data override fun onViewCreated(view:

    View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.user.observe(viewLifecycleOwner) { user -> textView.text = user.name } } override fun onDestroy() { super.onDestroy() // not called yet } observe(viewLifecycleOwner) { user -> }
  23. 40.

    navController.popBackStack() // navigate back // observe data override fun onViewCreated(view:

    View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.user.observe(viewLifecycleOwner) { user -> textView.text = user.name } } override fun onDestroyView() { super.onDestroyView() // observer is removed. } observe(viewLifecycleOwner) { user -> }
  24. 43.

    class FooViewModel : ViewModel() { val snackbarMessage: LiveData<SnackbarMessage> = MutableLiveData()

    } // viewModel // observe data override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.snackbarMessage.observe(viewLifecycleOwner) { message -> // show snackbar } }
  25. 44.

    class FooViewModel : ViewModel() { val snackbarMessage: LiveData<Event<SnackbarMessage>> = MutableLiveData()

    } // viewModel // observe data override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.snackbarMessage.observe(viewLifecycleOwner) { message -> // show snackbar } }
  26. 45.

    class FooViewModel : ViewModel() { val snackbarMessage: LiveData<Event<SnackbarMessage>> = MutableLiveData()

    } // viewModel // observe data override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.snackbarMessage.observe(viewLifecycleOwner) { message -> // show snackbar } } // Event.kt from https://github.com/google/iosched LiveData<Event<SnackbarMessage>>
  27. 46.

    class FooViewModel : ViewModel() { // Event.kt from https://github.com/google/iosched val

    snackbarMessage: LiveData<Event<SnackbarMessage>> = MutableLiveData() } // viewModel // observe data override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) viewModel.snackbarMessage.observe(viewLifecycleOwner) { event -> event.getContentIfNotHandled()?.let { message -> // show snackbar } } }
  28. 52.

    // scope for viewModel private val activityScopedViewModel: FooViewModel by activityViewModels

    { viewModelFactory } private val fragmentScopedViewModel: BarViewModel by viewModels { viewModelFactory } Activity Scope ≒ App Scope
  29. 53.

    // scope for viewModel private val activityScopedViewModel: FooViewModel by activityViewModels

    { viewModelFactory } private val fragmentScopedViewModel: BarViewModel by viewModels { viewModelFactory } Activity Scope ≒ App Scope … Fragment Scope Fragment Scope