Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Navigation Component 実践編

054312bb8749ab2405c3c5364bc1be1e?s=47 yoppie
December 03, 2019

Navigation Component 実践編

054312bb8749ab2405c3c5364bc1be1e?s=128

yoppie

December 03, 2019
Tweet

Transcript

  1. /BWJHBUJPO$PNQPOFOU ࣮ફฤ

  2. 'BDFCPPLIJLPXBJJEF5XJUUFS!ZPQQJF@Y (JUIVCZPTIJZB92JJUBZPQQJF@Y ϒϩάIUUQTZPQQJFYIBUFOBCMPHDPN ZPQQJF

  3. ͪΐͬͱখ࿩

  4. None
  5. %SPJE,BJHJ 

  6. 'SBHNFOU$POUBJOFS7JFX ͱ͸

  7. /BWJHBUJPO$PNQPOFOU ࣮ફฤ

  8. w "OESPJE+FUQBDLʹؚ·Ε͍ͯΔίϯϙʔωϯτ w "DUJWJUZ΍'SBHNFOUؒͷը໘ભҠΛγϯϓϧʹ࣮૷Ͱ͖Δ
 w ར఺ w 'SBHNFOU5SBOTBDUJPOͷॲཧΛϥΠϒϥϦ͕ߦ͏఺ w %FFQ-JOLͷ࣮૷ͷ؆қԽ

    w 4BGF"SHTΛ༻͍ͨܕ҆શͷ஋౉͠ w ը໘ભҠͷύλʔϯΛ9.-ʹఆٛ͠ՄࢹԽ
 /BWJHBUJPO(SBQI /BWJHBUJPO$PNQPOFOU
  9. None
  10. 4IBSFE7JFX.PEFM
 Λ༻͍ͨ஋ڞ༗

  11. ՝୊  'SBHNFOU͔Β'SBHNFOU΁஋౉͠Λ͢Δ৔߹
 ௨ৗ4BGF"SHTΛ༻͍ͨܕ҆શͷ஋౉͢͠Δ
 
 ͔͠͠ϗετ͍ͯ͠Δ"DUJWJUZͱ֤'SBHNFOUͰԿ͔Λ ڞ༗͢Δ͜ͱ͕Ͱ͖ͳ͍
  5PPMCBSͷ5JUMFͷมߋ΍ɺ4OBDLCBSͷදࣔΛ
 ֤'SBHNFOUͰߦͳΘͣ"DUJWJUZʹ·ͱΊ͍ͨ

  12. Activity Fragment 1 Fragment 4 Fragment 3 Fragment 2 SharedViewModel

    ղܾࡦ
  13. 4IBSFE7JFX.PEFMͷྫ class SharedViewModel : ViewModel(){ val fragmentType = MutableLiveData<FragmentType>().apply {

    this.value = FragmentType.FIRST } } enum class FragmentType(val type: String) { FIRST("first"), SECOND("second"), THIRD("third"), FOURTH("fourth") }
  14. "DUJWJUZͰ0CTFSWF val sharedViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java) sharedViewModel.fragmentType.observe(this, Observer { value ->

    value?.let { Snackbar.make( findViewById(android.R.id.content), it.type, Snackbar.LENGTH_SHORT ).show() } }) 4IBSFE7JFX.PEFMͷGSBHNFOU5ZQF͕มߋ͞Εͨ࣌ʹ 4OBDLCBS͕දࣔ͞ΕΔ
  15. 'SBHNFOUͰQPTU7BMVF sharedViewModel = ViewModelProviders.of(requireActivity()).get(SharedViewModel::class.java) snackbarButton.clicks().subscribe { sharedViewModel.fragmentType.postValue(FragmentType.FIRST) } "DUJWJUZͰ0CTFSWF͍ͯ͠ΔͷͰɺ
 'SBHNFOUͷ4IBSFE7JFX.PEFMͷΠϯελϯεΛ

    7JFX.PEFM1SPWJEFSTPG ͷҾ਺ʹSFRVJSF"DUJWJUZ Λ
 ࢦఆ͠਌ͷ"DUJWJUZʹͻ΋͚ͮͯ࡞੒
  16. ݁Ռ 4IBSFE7JFX.PEFMΛ࡞Δ͜ͱͰɺ ϗετ͍ͯ͠Δ"DUJWJUZͱ
 ֤'SBHNFOUͰ஋Λڞ༗ "DUJWJUZʹॲཧΛू໿

  17. ը໘ભҠޙͱ
 ը໘ભҠ࣌ͷ෼ذॲཧ

  18. ՝୊ "DUJWJUZ͕࣋ͭ5PPMCBS΍'MPBUJOH"DUJPO#VUUPOͳͲͷ 7JFXͷڍಈΛ'SBHNFOUʹґଘͯ͠มߋͨ͠Γɺ 'SBHNFOUؒͷը໘ભҠ࣌ʹม͍͑ͨ ͔͠͠ɺ'SBHNFOUʹ"DUJWJUZ͕࣋ͭ7JFXͷڍಈͷॲཧΛ ॻ͖ͨ͘ͳ͍ why? val toolbar =

    view.findViewById<Toolbar>(R.id.toolbar) requireActivity().setSupportActionBar(toolbar)
  19. 'SBHNFOUʹґଘͨ͠ڍಈͷมߋ
 ͳͷͰ'SBHNFOUͰॻ͖ͨ͘ͳΔ 
 ͔͠͠5PPMCBS͸"DUJWJUZ͕อ༗ͯ͠ ͍ΔͷͰɺอकੑͷ؍఺͔Β "DUJWJUZͰॻ͘΂͖ )PNF'SBHNFOUͷ৔߹ͷΈ
 5PPMCBSͷ໭ΔϘλϯԡԼ࣌ ͷڍಈΛมߋ͍ͨ͠


  20. ղܾࡦ /BW$POUSPMMFSͷ DVSSFOU%FTUJOBUJPO
 BEE0O%FTUJOBUJPO$IBOHFE-JTUFOFS 
 Λར༻

  21. binding.toolbar .navigationClicks() .filter { navController.currentDestination != null } .subscribe {

    when (navController.currentDestination!!.id) { R.id.homeFragment -> finish() R.id.secondFragment -> navController.navigate( SecondFragmentDirections.homeToFirst() ) } } navController = findNavController(R.id.container_fragment) 'SBHNFOU͝ͱʹ
 5PPMCBSͷॲཧΛ෼ذ
  22. navController.addOnDestinationChangedListener { _, destination, _ -> when (destination.id) { R.id.firstFragment

    -> binding.toolbarButton.visibility = View.GONE R.id.secondFragment -> binding.toolbarButton.visibility = View.VISIBLE } } 'SBHNFOUؒͷը໘ભҠ࣌ ը໘ભҠ࣌ʹ5PPMCBSʹ͋Δ#VUUPOͷWJTJWJMJUZΛมߋ
  23. 'SBHNFOUʹґଘ΋͘͠͸'SBHNFOU ؒͷը໘ભҠʹΑΔ"DUJWJUZ͕࣋ͭ 7JFX ࠓճͷྫͩͱ5PPMCBS ͷ
 ڍಈมߋΛ'SBHNFOUʹॻ͔ͣʹ "DUJWJUZʹهࡌͰ͖ͨ ݁Ռ

  24. #PUUPN/BWJHBUJPO7JFXͱͷ ซ༻࣌ͷঢ়ଶอ࣋

  25. ՝୊ #PUUPN/BWJHBUJPO7JFXͱ/BWJHBUJPO$PNQPOFOUΛซ༻ ͢Δ৔߹ɺσϑΥϧτͰλϒ੾Γସ͑࣌ʹ'SBHNFOU͕࠶ ੜ੒͞Ε·͢ɻ Αͬͯɺ࠶ੜ੒͞Εͳ͍Α͏ʹ͢ΔͨΊʹ
 'SBHNFOUͷঢ়ଶอ࣋Λ࣮૷͢Δඞཁ͕
 ͋Γ·͢ɻ #PUUPN/BWJHBUJPO7JFX

  26. ղܾࡦ 'SBHNFOU/BWJHBUPSΫϥεΛܧঝͨ͠ $VTUPN/BWJHBUPSΫϥεΛ࡞੒͠ɺ
 ঢ়ଶอ࣋͞ΕΔΑ͏ʹOBWJHBUF Λ্ॻ͖

  27. @Navigator.Name("custom_fragment") class CustomNavigator( private val context: Context, private val manager:

    FragmentManager, private val containerId: Int ) : FragmentNavigator(context, manager, containerId) { @Suppress("DEPRECATION") override fun navigate( destination: Destination, args: Bundle?, navOptions: NavOptions?, navigatorExtras: Navigator.Extras? ): NavDestination? { // ... } }
  28. if (manager.isStateSaved) { return null } var className = destination.className

    if (className[0] == '.') { className = context.packageName + className } val tag = destination.id.toString() val transaction = manager.beginTransaction() val currentFragment = manager.primaryNavigationFragment if (currentFragment != null) { transaction.hide(currentFragment) } var fragment = manager.findFragmentByTag(tag) if (fragment == null) { fragment = instantiateFragment(context, manager, className, args) transaction.add(containerId, fragment, tag) } fragment.arguments = args transaction.show(fragment) transaction.setPrimaryNavigationFragment(fragment) transaction.commit() return destination Ξχϝʔγϣϯͱ
 #BDL4UBDLपΓͷ ॲཧ͸ল͍͍ͯ·͢
  29. class CustomNavHostFragment : NavHostFragment() { override fun createFragmentNavigator( ): Navigator<out

    FragmentNavigator.Destination> { return CustomNavigator(requireContext(), childFragmentManager, id) } } /BW)PTU'SBHNFOUͷDSFBUF'SBHNFOU/BWJHBUPS ͷ
 ໭Γ஋͕'SBHNFOU/BWJHBUPSͳͷͰܧঝͨ͠ $VTUPN/BW)PTU'SBHNFOUΛ࡞੒্͠ॻ͖
  30. <navigation xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/bottom_navigation" app:startDestination="@+id/tab1"> <custom_fragment android:id="@+id/tab1" android:name="hoge.HogeFragment" android:label="tab1" android:tag="tab1"

    /> OBWJHBUJPOϨΠΞ΢τ $VTUPN/BWJHBUPSΫϥεʹ͚ͭͨ
 !/BWJHBUPS/BNFΞϊςʔγϣϯͷҾ਺ʹࢦఆ͍ͯ͠Δ DVTUPN@GSBHNFOUΛར༻
  31. <fragment android:id="@+id/bottom_navigation_view_fragment" android:name="hoge.navigation.CustomNavHostFragment" android:layout_width="match_parent" android:layout_height="wrap_content" app:defaultNavHost="true" app:layout_constraintBottom_toTopOf="@id/bottom_navigation_view" app:layout_constraintTop_toBottomOf="@+id/toolbar" app:navGraph="@navigation/navigation" />

    <com.google.android.material.bottomnavigation.BottomNavigationView android:id="@+id/bottom_navigation_view" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="?android:attr/windowBackground" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:menu="@menu/bottom_navigation_menu" /> BOESPJEYOBWJHBUJPOGSBHNFOU/BW)PTU'SBHNFOU Ͱ͸ͳࣗ͘࡞ͨ͠$VTUPN/BW)PTU'SBHNFOUΛࢦఆ
  32. ݁Ռ 'SBHNFOUͷঢ়ଶอ࣋ʹ੒ޭ

  33. ࠷ޙʹ /BWJHBUJPO$PNQPOFOUΛ࢖͏ͱ "DUJWJUZ΍'SBHNFOUؒͷը໘ભҠΛ
 γϯϓϧʹ࣮૷Ͱ͖Δ ࣮ફͰಋೖ͢ΔͱͳΔͱ
 ӡ༻΍อकੑΛߟྀ͢ΔΑ͏ʹͳΓ ૑ҙ޻෉͕ඞཁ