Browse Source

Initial tablet NavigationRailView implementation

TODO:
- Make the side nav go beside the toolbar too
- Extract out common main_activity stuff to remove duplicated code
arkon 3 years ago
parent
commit
de35a4c62a

+ 1 - 1
app/build.gradle.kts

@@ -142,7 +142,7 @@ dependencies {
     implementation("androidx.work:work-runtime-ktx:2.5.0")
 
     // UI library
-    implementation("com.google.android.material:material:1.3.0")
+    implementation("com.google.android.material:material:1.4.0-beta01")
 
     "standardImplementation"("com.google.firebase:firebase-core:19.0.0")
 

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryController.kt

@@ -367,7 +367,7 @@ class LibraryController(
                 actionMode!!,
                 R.menu.library_selection
             ) { onActionItemClicked(it!!) }
-            (activity as? MainActivity)?.showBottomNav(visible = false, collapse = true)
+            (activity as? MainActivity)?.showNav(visible = false, collapse = true)
         }
     }
 
@@ -476,7 +476,7 @@ class LibraryController(
         selectionRelay.call(LibrarySelectionEvent.Cleared())
 
         binding.actionToolbar.hide()
-        (activity as? MainActivity)?.showBottomNav(visible = true, collapse = true)
+        (activity as? MainActivity)?.showNav(visible = true, collapse = true)
 
         actionMode = null
     }

+ 49 - 35
app/src/main/java/eu/kanade/tachiyomi/ui/main/MainActivity.kt

@@ -24,6 +24,7 @@ import com.bluelinelabs.conductor.Router
 import com.bluelinelabs.conductor.RouterTransaction
 import com.google.android.material.appbar.AppBarLayout
 import com.google.android.material.behavior.HideBottomViewOnScrollBehavior
+import com.google.android.material.navigation.NavigationBarView
 import dev.chrisbanes.insetter.applyInsetter
 import eu.kanade.tachiyomi.BuildConfig
 import eu.kanade.tachiyomi.Migrations
@@ -76,7 +77,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
     }
 
     lateinit var tabAnimator: ViewHeightAnimator
-    private lateinit var bottomNavAnimator: ViewHeightAnimator
+    private var bottomNavAnimator: ViewHeightAnimator? = null
 
     private var isConfirmingExit: Boolean = false
     private var isHandlingShortcut: Boolean = false
@@ -109,7 +110,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
                 margin()
             }
         }
-        binding.bottomNav.applyInsetter {
+        binding.bottomNav?.applyInsetter {
             type(navigationBars = true) {
                 padding()
             }
@@ -131,23 +132,26 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         }
 
         tabAnimator = ViewHeightAnimator(binding.tabs, 0L)
-        bottomNavAnimator = ViewHeightAnimator(binding.bottomNav)
 
-        // If bottom nav is hidden, make it visible again when the app bar is expanded
-        binding.appbar.addOnOffsetChangedListener(
-            AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
-                if (verticalOffset == 0) {
-                    showBottomNav(true)
+        if (binding.bottomNav != null) {
+            bottomNavAnimator = ViewHeightAnimator(binding.bottomNav!!)
+
+            // If bottom nav is hidden, make it visible again when the app bar is expanded
+            binding.appbar.addOnOffsetChangedListener(
+                AppBarLayout.OnOffsetChangedListener { _, verticalOffset ->
+                    if (verticalOffset == 0) {
+                        showNav(true)
+                    }
                 }
-            }
-        )
+            )
 
-        // Set behavior of bottom nav
-        preferences.hideBottomBar()
-            .asImmediateFlow { setBottomNavBehaviorOnScroll() }
-            .launchIn(lifecycleScope)
+            // Set behavior of bottom nav
+            preferences.hideBottomBar()
+                .asImmediateFlow { setBottomNavBehaviorOnScroll() }
+                .launchIn(lifecycleScope)
+        }
 
-        binding.bottomNav.setOnNavigationItemSelectedListener { item ->
+        nav.setOnItemSelectedListener { item ->
             val id = item.itemId
 
             val currentRoot = router.backstack.firstOrNull()
@@ -256,9 +260,9 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
     private fun setExtensionsBadge() {
         val updates = preferences.extensionUpdatesCount().get()
         if (updates > 0) {
-            binding.bottomNav.getOrCreateBadge(R.id.nav_browse).number = updates
+            nav.getOrCreateBadge(R.id.nav_browse).number = updates
         } else {
-            binding.bottomNav.removeBadge(R.id.nav_browse)
+            nav.removeBadge(R.id.nav_browse)
         }
     }
 
@@ -350,7 +354,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         super.onDestroy()
 
         // Binding sometimes isn't actually instantiated yet somehow
-        binding?.bottomNav.setOnNavigationItemSelectedListener(null)
+        nav.setOnItemSelectedListener(null)
         binding?.toolbar.setNavigationOnClickListener(null)
     }
 
@@ -385,7 +389,7 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
 
     fun setSelectedNavItem(itemId: Int) {
         if (!isFinishing) {
-            binding.bottomNav.selectedItemId = itemId
+            nav.selectedItemId = itemId
         }
     }
 
@@ -407,11 +411,11 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         binding.appbar.setExpanded(true)
 
         if ((from == null || from is RootController) && to !is RootController) {
-            showBottomNav(visible = false, collapse = true)
+            showNav(visible = false, collapse = true)
         }
         if (to is RootController) {
             // Always show bottom nav again when returning to a RootController
-            showBottomNav(visible = true, collapse = from !is RootController)
+            showNav(visible = true, collapse = from !is RootController)
         }
 
         if (from is TabbedController) {
@@ -447,21 +451,28 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         }
     }
 
-    fun showBottomNav(visible: Boolean, collapse: Boolean = false) {
-        val layoutParams = binding.bottomNav.layoutParams as CoordinatorLayout.LayoutParams
-        val bottomViewNavigationBehavior = layoutParams.behavior as? HideBottomViewOnScrollBehavior
-        if (visible) {
-            if (collapse) {
-                bottomNavAnimator.expand()
-            }
+    fun showNav(visible: Boolean, collapse: Boolean = false) {
+        binding.bottomNav?.let {
+            val layoutParams = it.layoutParams as CoordinatorLayout.LayoutParams
+            val bottomViewNavigationBehavior =
+                layoutParams.behavior as? HideBottomViewOnScrollBehavior
+            if (visible) {
+                if (collapse) {
+                    bottomNavAnimator?.expand()
+                }
 
-            bottomViewNavigationBehavior?.slideUp(binding.bottomNav)
-        } else {
-            if (collapse) {
-                bottomNavAnimator.collapse()
+                bottomViewNavigationBehavior?.slideUp(it)
+            } else {
+                if (collapse) {
+                    bottomNavAnimator?.collapse()
+                }
+
+                bottomViewNavigationBehavior?.slideDown(it)
             }
+        }
 
-            bottomViewNavigationBehavior?.slideDown(binding.bottomNav)
+        binding.sideNav?.let {
+            it.isVisible = visible
         }
     }
 
@@ -484,9 +495,9 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
     }
 
     private fun setBottomNavBehaviorOnScroll() {
-        showBottomNav(visible = true)
+        showNav(visible = true)
 
-        binding.bottomNav.updateLayoutParams<CoordinatorLayout.LayoutParams> {
+        binding.bottomNav?.updateLayoutParams<CoordinatorLayout.LayoutParams> {
             behavior = when {
                 preferences.hideBottomBar().get() -> HideBottomViewOnScrollBehavior<View>()
                 else -> null
@@ -494,6 +505,9 @@ class MainActivity : BaseViewBindingActivity<MainActivityBinding>() {
         }
     }
 
+    private val nav: NavigationBarView
+        get() = binding.bottomNav ?: binding.sideNav!!
+
     companion object {
         // Shortcut actions
         const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/ui/recent/updates/UpdatesController.kt

@@ -182,7 +182,7 @@ class UpdatesController :
                 actionMode!!,
                 R.menu.updates_chapter_selection
             ) { onActionItemClicked(it!!) }
-            (activity as? MainActivity)?.showBottomNav(visible = false, collapse = true)
+            (activity as? MainActivity)?.showNav(visible = false, collapse = true)
         }
 
         toggleSelection(position)
@@ -380,7 +380,7 @@ class UpdatesController :
         adapter?.clearSelection()
 
         binding.actionToolbar.hide()
-        (activity as? MainActivity)?.showBottomNav(visible = true, collapse = true)
+        (activity as? MainActivity)?.showNav(visible = true, collapse = true)
 
         actionMode = null
     }

+ 0 - 0
app/src/main/res/color/bottom_nav_selector.xml → app/src/main/res/color/nav_selector.xml


+ 99 - 0
app/src/main/res/layout-sw600dp/main_activity.xml

@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.coordinatorlayout.widget.CoordinatorLayout 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/root_coordinator"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <eu.kanade.tachiyomi.widget.ElevationAppBarLayout
+        android:id="@+id/appbar"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:fitsSystemWindows="true">
+
+        <com.google.android.material.appbar.MaterialToolbar
+            android:id="@+id/toolbar"
+            android:layout_width="match_parent"
+            android:layout_height="?attr/actionBarSize"
+            android:background="?attr/colorPrimary"
+            android:theme="?attr/actionBarTheme"
+            app:layout_scrollFlags="scroll|enterAlways" />
+
+        <com.google.android.material.tabs.TabLayout
+            android:id="@+id/tabs"
+            style="@style/Theme.Widget.Tabs"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+
+        <FrameLayout
+            android:id="@+id/downloaded_only"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@color/green"
+            android:visibility="gone"
+            tools:visibility="visible">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:padding="4dp"
+                android:text="@string/label_downloaded_only"
+                android:textColor="@color/md_white_1000" />
+
+        </FrameLayout>
+
+        <FrameLayout
+            android:id="@+id/incognito_mode"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:background="@color/md_grey_800"
+            android:visibility="gone"
+            tools:visibility="visible">
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center"
+                android:padding="4dp"
+                android:text="@string/pref_incognito_mode"
+                android:textColor="@color/md_white_1000" />
+
+        </FrameLayout>
+
+    </eu.kanade.tachiyomi.widget.ElevationAppBarLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_behavior="@string/appbar_scrolling_view_behavior">
+
+        <com.google.android.material.navigationrail.NavigationRailView
+            android:id="@+id/side_nav"
+            style="@style/Widget.MaterialComponents.NavigationRailView.Colored"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            app:itemIconTint="@color/nav_selector"
+            app:itemTextColor="@color/nav_selector"
+            app:labelVisibilityMode="labeled"
+            app:menu="@menu/main_nav" />
+
+        <com.bluelinelabs.conductor.ChangeHandlerFrameLayout
+            android:id="@+id/controller_container"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_weight="1" />
+
+    </LinearLayout>
+
+    <com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
+        android:id="@+id/root_fab"
+        style="@style/Theme.Widget.FAB"
+        android:visibility="gone"
+        tools:icon="@drawable/ic_add_24dp"
+        tools:text="Action"
+        tools:visibility="visible" />
+
+</androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 3 - 3
app/src/main/res/layout/main_activity.xml

@@ -85,10 +85,10 @@
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="bottom"
-        app:itemIconTint="@color/bottom_nav_selector"
-        app:itemTextColor="@color/bottom_nav_selector"
+        app:itemIconTint="@color/nav_selector"
+        app:itemTextColor="@color/nav_selector"
         app:labelVisibilityMode="labeled"
         app:layout_insetEdge="bottom"
-        app:menu="@menu/bottom_nav" />
+        app:menu="@menu/main_nav" />
 
 </androidx.coordinatorlayout.widget.CoordinatorLayout>

+ 0 - 0
app/src/main/res/menu/bottom_nav.xml → app/src/main/res/menu/main_nav.xml