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

Bottom Navigationでタブの状態を保持する

Bottom Navigationでタブの状態を保持する

shibuya.apk #17

85cab5fdf09afe3ee78ce3667681915a?s=128

Keisuke Kobayashi

August 04, 2017
Tweet

Transcript

  1. Bottom NavigationͰ λϒͷঢ়ଶΛอ࣋͢Δ Keisuke Kobayashi / @kobakei shibuya.apk #17

  2. About me • Keisuke Kobayashi • GitHub, Qiita: kobakei •

    Twitter: kobakei122 • Kyash, Inc
  3. YouTubeͷ Bottom Navigation

  4. ԼʹεΫϩʔϧ
 ͨ͠ঢ়ଶ

  5. None
  6. εΫϩʔϧҐஔ͕ લճͷ··

  7. λϒ੾Γସ͑࣌ʹ
 ঢ়ଶΛอ࣋Ͱ͖ͯΔʂ

  8. Ͳ͏΍ͬͯʁ

  9. ࣮૷ • ViewPagerΛ࢖͏ • λϒબ୒࣌ʹɺsetSelectionͰϖʔδΛ੾Γସ͑Δ • εϫΠϓͰͷ੾Γସ͑͸ΨΠυϥΠϯతʹNGͳͷͰɺεϫ ΠϓΛແޮԽ͓ͯ͘͠ • YouTube΋ଟ෼͜ͷ࣮૷

    • uiautomatorviewerͰViewPagerΛ֬ೝ
  10. class FixedViewPager @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null

    ): ViewPager(context, attrs) { override fun onTouchEvent(ev: MotionEvent?): Boolean { return false } override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { return false } }
  11. class FixedViewPager @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null

    ): ViewPager(context, attrs) { override fun onTouchEvent(ev: MotionEvent?): Boolean { return false } override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean { return false } } λονΛແޮԽ
  12. class MainPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) { override fun getCount(): Int {

    return 3 } override fun getItem(position: Int): Fragment { return when (position) { 0 -> OneFragment.newInstance() 1 -> TwoFragment.newInstance() 2 -> ThreeFragment.newInstance() else -> throw IllegalArgumentException() } } }
  13. class MainPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) { override fun getCount(): Int {

    return 3 } override fun getItem(position: Int): Fragment { return when (position) { 0 -> OneFragment.newInstance() 1 -> TwoFragment.newInstance() 2 -> ThreeFragment.newInstance() else -> throw IllegalArgumentException() } } } λϒͷ਺
  14. class MainPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) { override fun getCount(): Int {

    return 3 } override fun getItem(position: Int): Fragment { return when (position) { 0 -> OneFragment.newInstance() 1 -> TwoFragment.newInstance() 2 -> ThreeFragment.newInstance() else -> throw IllegalArgumentException() } } } ֤λϒͷFragmentΛฦ͢
  15. <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <com.roughike.bottombar.BottomBar android:id="@+id/bottomBar" android:layout_width="match_parent" android:layout_height="@dimen/bottom_bar_height" android:layout_alignParentBottom="true" app:bb_tabXmlResource="@xml/bottombar"/> <com.example.FixedViewPager

    android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/bottomBar"/> </RelativeLayout>
  16. // MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { // লུ pager.adapter

    = MainPagerAdapter(supportFragmentManager) bottomBar.setOnTabSelectListener { tabId -> when (tabId) { R.id.tab1 -> showTab1() R.id.tab2 -> showTab2() R.id.tab3 -> showTab3() } } }
  17. // MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { // লུ pager.adapter

    = MainPagerAdapter(supportFragmentManager) bottomBar.setOnTabSelectListener { tabId -> when (tabId) { R.id.tab1 -> showTab1() R.id.tab2 -> showTab2() R.id.tab3 -> showTab3() } } } λϒબ୒࣌ʹɺදࣔ಺༰Λ੾Γସ͑
  18. // MainActivity.kt private fun showTab1() { // Clear back stack

    (1..supportFragmentManager.backStackEntryCount).forEach { supportFragmentManager.popBackStack() } // Change page without animation pager.setCurrentItem(0, false) }
  19. ϥΠϑαΠΫϧͷ໰୊ • ͋Δλϒ͕දࣔ͞Εͨͱ͖ʹԿ͔ॲཧΛͨ͠ ͍৔߹ɺద੾ͳϥΠϑαΠΫϧΠϕϯτ͕ͳ͍

  20. Why? • ViewPager͸εϜʔζʹεϫΠϓͰ͖ΔΑ͏ʹ ͢ΔͨΊɺද͍ࣔͯ͠Δλϒͱ྆ྡͷλϒΛ ද͍ࣔͯ͠Δ • λϒ͕දࣔ͞ΕΔΑΓઌʹonResume͕ݺ͹ ΕΔ

  21. ղܾࡦ • BottomBarͷλϒબ୒ɾඇબ୒ΠϕϯτΛ Fragmentʹ౉͢

  22. // ֤λϒͷFragement͸͜ͷΠϯλϑΣʔεΛ࣮૷͢Δ interface RootFragment { fun onTabSelected() fun onTabUnselected() }

  23. class MainPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) { var currentFragment: Fragment? = null

    override fun getCount(): Int {...} override fun getItem(position: Int): Fragment {...} override fun setPrimaryItem(container: ViewGroup?, position: Int, obj: Any?) { if (currentFragment != obj) { currentFragment = obj as Fragment } super.setPrimaryItem(container, position, obj) } }
  24. class MainPagerAdapter(fm: FragmentManager): FragmentPagerAdapter(fm) { var currentFragment: Fragment? = null

    override fun getCount(): Int {...} override fun getItem(position: Int): Fragment {...} override fun setPrimaryItem(container: ViewGroup?, position: Int, obj: Any?) { if (currentFragment != obj) { currentFragment = obj as Fragment } super.setPrimaryItem(container, position, obj) } } ݱࡏͷFragmentΛอ࣋
  25. // MainActivity.kt
 override fun onCreate(savedInstanceState: Bundle?) { // ... //

    ViewPager pager.adapter = MainPagerAdapter(supportFragmentManager) // bottomBar.setOnTabSelectListener { tabId -> dispatchUnselect() when (tabId) { R.id.tab1 -> showTab1() R.id.tab2 -> showTab2() R.id.tab3 -> showTab3() } dispatchSelect() } }
  26. // MainActivity.kt override fun onCreate(savedInstanceState: Bundle?) { // ... //

    ViewPager pager.adapter = MainPagerAdapter(supportFragmentManager) // bottomBar.setOnTabSelectListener { tabId -> dispatchUnselect() when (tabId) { R.id.tab1 -> showTab1() R.id.tab2 -> showTab2() R.id.tab3 -> showTab3() } dispatchSelect() } } Fragment੾ସͷલޙͰ
 ΠϕϯτΛൃՐ
  27. private fun dispatchSelect() { val mainAdapter = pager.adapter as? MainPagerAdapter

    val fragment = mainAdapter?.currentFragment as? RootFragment fragment?.onTabSelected() } private fun dispatchUnselect() { val mainAdapter = pager.adapter as? MainPagerAdapter val fragment = mainAdapter?.currentFragment as? RootFragment fragment?.onTabUnselected() }
  28. ·ͱΊ • BottomNavigationͷλϒͷঢ়ଶอ࣋ʹ͸ɺ
 εϫΠϓ͠ͳ͍ViewPagerΛ࢖͏ • දࣔɾඇදࣔ࣌ʹԿ͔͍ͨ͠৔߹͸ɺ
 λϒબ୒ɾඇબ୒ΠϕϯτΛFragmentʹ౉͢

  29. Thanks!