Remove bottom nav behavior and add bottom padding to root controller contents

This commit is contained in:
arkon 2022-07-22 22:44:05 -04:00
parent 2b8d1bcc02
commit 4bf4b167a5
14 changed files with 22 additions and 154 deletions

View file

@ -44,6 +44,7 @@ import eu.kanade.presentation.components.FastScrollLazyColumn
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.SwipeRefreshIndicator import eu.kanade.presentation.components.SwipeRefreshIndicator
import eu.kanade.presentation.theme.header import eu.kanade.presentation.theme.header
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.topPaddingValues import eu.kanade.presentation.util.topPaddingValues
@ -112,7 +113,7 @@ fun ExtensionContent(
var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) } var trustState by remember { mutableStateOf<Extension.Untrusted?>(null) }
FastScrollLazyColumn( FastScrollLazyColumn(
contentPadding = WindowInsets.navigationBars.asPaddingValues() + topPaddingValues, contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
) { ) {
items( items(
items = state.items, items = state.items,

View file

@ -28,6 +28,7 @@ import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.theme.header import eu.kanade.presentation.theme.header
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.topPaddingValues import eu.kanade.presentation.util.topPaddingValues
@ -68,7 +69,7 @@ fun MigrateSourceList(
) { ) {
ScrollbarLazyColumn( ScrollbarLazyColumn(
modifier = Modifier.nestedScroll(nestedScrollInterop), modifier = Modifier.nestedScroll(nestedScrollInterop),
contentPadding = WindowInsets.navigationBars.asPaddingValues() + topPaddingValues, contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
) { ) {
item(key = "title") { item(key = "title") {
Text( Text(

View file

@ -35,6 +35,7 @@ import eu.kanade.presentation.components.EmptyScreen
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.theme.header import eu.kanade.presentation.theme.header
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.topPaddingValues import eu.kanade.presentation.util.topPaddingValues
@ -92,7 +93,7 @@ fun SourceList(
) { ) {
ScrollbarLazyColumn( ScrollbarLazyColumn(
modifier = Modifier.nestedScroll(nestedScrollConnection), modifier = Modifier.nestedScroll(nestedScrollConnection),
contentPadding = WindowInsets.navigationBars.asPaddingValues() + topPaddingValues, contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
) { ) {
items( items(
items = state.items, items = state.items,

View file

@ -50,6 +50,7 @@ fun VerticalFastScroller(
thumbAllowed: () -> Boolean = { true }, thumbAllowed: () -> Boolean = { true },
thumbColor: Color = MaterialTheme.colorScheme.primary, thumbColor: Color = MaterialTheme.colorScheme.primary,
topContentPadding: Dp = Dp.Hairline, topContentPadding: Dp = Dp.Hairline,
bottomContentPadding: Dp = Dp.Hairline,
endContentPadding: Dp = Dp.Hairline, endContentPadding: Dp = Dp.Hairline,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
@ -76,7 +77,8 @@ fun VerticalFastScroller(
) )
} }
val heightPx = contentHeight.toFloat() - thumbTopPadding - listState.layoutInfo.afterContentPadding val thumbBottomPadding = with(LocalDensity.current) { bottomContentPadding.toPx() }
val heightPx = contentHeight.toFloat() - thumbTopPadding - thumbBottomPadding - listState.layoutInfo.afterContentPadding
val thumbHeightPx = with(LocalDensity.current) { ThumbLength.toPx() } val thumbHeightPx = with(LocalDensity.current) { ThumbLength.toPx() }
val trackHeightPx = heightPx - thumbHeightPx val trackHeightPx = heightPx - thumbHeightPx

View file

@ -43,6 +43,7 @@ import eu.kanade.presentation.components.RelativeDateHeader
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.history.components.HistoryItem import eu.kanade.presentation.history.components.HistoryItem
import eu.kanade.presentation.history.components.HistoryItemShimmer import eu.kanade.presentation.history.components.HistoryItemShimmer
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.shimmerGradient import eu.kanade.presentation.util.shimmerGradient
import eu.kanade.presentation.util.topPaddingValues import eu.kanade.presentation.util.topPaddingValues
@ -102,7 +103,7 @@ fun HistoryContent(
ScrollbarLazyColumn( ScrollbarLazyColumn(
modifier = Modifier modifier = Modifier
.nestedScroll(nestedScroll), .nestedScroll(nestedScroll),
contentPadding = WindowInsets.navigationBars.asPaddingValues() + topPaddingValues, contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues() + topPaddingValues,
state = scrollState, state = scrollState,
) { ) {
items(history) { item -> items(history) { item ->

View file

@ -11,6 +11,7 @@ import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
@Composable @Composable
@ -22,7 +23,7 @@ fun LazyLibraryGrid(
LazyVerticalGrid( LazyVerticalGrid(
modifier = modifier, modifier = modifier,
columns = if (columns == 0) GridCells.Adaptive(128.dp) else GridCells.Fixed(columns), columns = if (columns == 0) GridCells.Adaptive(128.dp) else GridCells.Fixed(columns),
contentPadding = PaddingValues(12.dp) + WindowInsets.navigationBars.asPaddingValues(), contentPadding = bottomNavPaddingValues + PaddingValues(12.dp) + WindowInsets.navigationBars.asPaddingValues(),
verticalArrangement = Arrangement.spacedBy(12.dp), verticalArrangement = Arrangement.spacedBy(12.dp),
horizontalArrangement = Arrangement.spacedBy(12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp),
content = content, content = content,

View file

@ -22,7 +22,9 @@ import eu.kanade.domain.manga.model.MangaCover
import eu.kanade.presentation.components.Badge import eu.kanade.presentation.components.Badge
import eu.kanade.presentation.components.BadgeGroup import eu.kanade.presentation.components.BadgeGroup
import eu.kanade.presentation.components.TextButton import eu.kanade.presentation.components.TextButton
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.horizontalPadding
import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.selectedBackground import eu.kanade.presentation.util.selectedBackground
import eu.kanade.presentation.util.verticalPadding import eu.kanade.presentation.util.verticalPadding
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -39,7 +41,7 @@ fun LibraryList(
onGlobalSearchClicked: () -> Unit, onGlobalSearchClicked: () -> Unit,
) { ) {
LazyColumn( LazyColumn(
contentPadding = WindowInsets.navigationBars.asPaddingValues(), contentPadding = bottomNavPaddingValues + WindowInsets.navigationBars.asPaddingValues(),
) { ) {
item { item {
if (searchQuery.isNullOrEmpty().not()) { if (searchQuery.isNullOrEmpty().not()) {

View file

@ -26,6 +26,7 @@ import eu.kanade.presentation.components.PreferenceRow
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.ScrollbarLazyColumn import eu.kanade.presentation.components.ScrollbarLazyColumn
import eu.kanade.presentation.components.SwitchPreference import eu.kanade.presentation.components.SwitchPreference
import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.presentation.util.quantityStringResource import eu.kanade.presentation.util.quantityStringResource
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@ -56,7 +57,7 @@ fun MoreScreen(
}, },
) { paddingValues -> ) { paddingValues ->
ScrollbarLazyColumn( ScrollbarLazyColumn(
contentPadding = paddingValues + WindowInsets.navigationBars.asPaddingValues(), contentPadding = bottomNavPaddingValues + paddingValues + WindowInsets.navigationBars.asPaddingValues(),
) { ) {
item { item {
LogoHeader() LogoHeader()

View file

@ -34,9 +34,7 @@ import eu.kanade.presentation.components.MangaBottomActionMenu
import eu.kanade.presentation.components.Scaffold import eu.kanade.presentation.components.Scaffold
import eu.kanade.presentation.components.SwipeRefreshIndicator import eu.kanade.presentation.components.SwipeRefreshIndicator
import eu.kanade.presentation.components.VerticalFastScroller import eu.kanade.presentation.components.VerticalFastScroller
import eu.kanade.presentation.util.NavBarVisibility import eu.kanade.presentation.util.bottomNavPaddingValues
import eu.kanade.presentation.util.isScrollingDown
import eu.kanade.presentation.util.isScrollingUp
import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.plus
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
@ -56,7 +54,6 @@ fun UpdateScreen(
onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit, onDownloadChapter: (List<UpdatesItem>, ChapterDownloadAction) -> Unit,
onUpdateLibrary: () -> Unit, onUpdateLibrary: () -> Unit,
onBackClicked: () -> Unit, onBackClicked: () -> Unit,
toggleNavBarVisibility: (NavBarVisibility) -> Unit,
// For bottom action menu // For bottom action menu
onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit, onMultiBookmarkClicked: (List<UpdatesItem>, bookmark: Boolean) -> Unit,
onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit, onMultiMarkAsReadClicked: (List<UpdatesItem>, read: Boolean) -> Unit,
@ -86,13 +83,6 @@ fun UpdateScreen(
// First and last selected index in list // First and last selected index in list
val selectedPositions = remember(uiModels) { arrayOf(-1, -1) } val selectedPositions = remember(uiModels) { arrayOf(-1, -1) }
when {
selected.isEmpty() &&
updatesListState.isScrollingUp() -> toggleNavBarVisibility(NavBarVisibility.SHOW)
selected.isNotEmpty() ||
updatesListState.isScrollingDown() -> toggleNavBarVisibility(NavBarVisibility.HIDE)
}
val internalOnBackPressed = { val internalOnBackPressed = {
if (selected.isNotEmpty()) { if (selected.isNotEmpty()) {
selected.clear() selected.clear()
@ -133,7 +123,7 @@ fun UpdateScreen(
) )
}, },
) { contentPadding -> ) { contentPadding ->
val contentPaddingWithNavBar = contentPadding + val contentPaddingWithNavBar = bottomNavPaddingValues + contentPadding +
WindowInsets.navigationBars.only(WindowInsetsSides.Bottom).asPaddingValues() WindowInsets.navigationBars.only(WindowInsetsSides.Bottom).asPaddingValues()
SwipeRefresh( SwipeRefresh(
@ -153,6 +143,7 @@ fun UpdateScreen(
VerticalFastScroller( VerticalFastScroller(
listState = updatesListState, listState = updatesListState,
topContentPadding = contentPaddingWithNavBar.calculateTopPadding(), topContentPadding = contentPaddingWithNavBar.calculateTopPadding(),
bottomContentPadding = contentPaddingWithNavBar.calculateBottomPadding(),
endContentPadding = contentPaddingWithNavBar.calculateEndPadding(LocalLayoutDirection.current), endContentPadding = contentPaddingWithNavBar.calculateEndPadding(LocalLayoutDirection.current),
) { ) {
LazyColumn( LazyColumn(

View file

@ -4,13 +4,12 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
private val horizontal = 16.dp private val horizontal = 16.dp
private val vertical = 8.dp private val vertical = 8.dp
val horizontalPadding = horizontal val horizontalPadding = horizontal
val verticalPadding = vertical val verticalPadding = vertical
val topPaddingValues = PaddingValues(top = vertical) val topPaddingValues = PaddingValues(top = vertical)
val bottomNavPaddingValues = PaddingValues(bottom = 96.dp)
const val ReadItemAlpha = .38f const val ReadItemAlpha = .38f

View file

@ -1,13 +0,0 @@
package eu.kanade.presentation.util
enum class NavBarVisibility {
SHOW,
HIDE
}
fun NavBarVisibility.toBoolean(): Boolean {
return when (this) {
NavBarVisibility.SHOW -> true
NavBarVisibility.HIDE -> false
}
}

View file

@ -10,8 +10,6 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import eu.kanade.presentation.components.ChapterDownloadAction import eu.kanade.presentation.components.ChapterDownloadAction
import eu.kanade.presentation.components.LoadingScreen import eu.kanade.presentation.components.LoadingScreen
import eu.kanade.presentation.updates.UpdateScreen import eu.kanade.presentation.updates.UpdateScreen
import eu.kanade.presentation.util.NavBarVisibility
import eu.kanade.presentation.util.toBoolean
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.download.DownloadService import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.download.model.Download import eu.kanade.tachiyomi.data.download.model.Download
@ -49,7 +47,6 @@ class UpdatesController :
onDownloadChapter = this::downloadChapters, onDownloadChapter = this::downloadChapters,
onUpdateLibrary = this::updateLibrary, onUpdateLibrary = this::updateLibrary,
onBackClicked = this::onBackClicked, onBackClicked = this::onBackClicked,
toggleNavBarVisibility = this::toggleNavBarVisibility,
// For bottom action menu // For bottom action menu
onMultiBookmarkClicked = { updatesItems, bookmark -> onMultiBookmarkClicked = { updatesItems, bookmark ->
presenter.bookmarkUpdates(updatesItems, bookmark) presenter.bookmarkUpdates(updatesItems, bookmark)
@ -80,15 +77,6 @@ class UpdatesController :
(activity as? MainActivity)?.moveToStartScreen() (activity as? MainActivity)?.moveToStartScreen()
} }
private fun toggleNavBarVisibility(navBarVisibility: NavBarVisibility) {
val showNavBar = navBarVisibility.toBoolean()
(activity as? MainActivity)?.showBottomNav(showNavBar)
}
/**
* Download selected items
* @param items list of selected [UpdatesItem]s
*/
private fun downloadChapters(items: List<UpdatesItem>, action: ChapterDownloadAction) { private fun downloadChapters(items: List<UpdatesItem>, action: ChapterDownloadAction) {
if (items.isEmpty()) return if (items.isEmpty()) return
viewScope.launch { viewScope.launch {

View file

@ -1,106 +0,0 @@
package eu.kanade.tachiyomi.widget
import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.bottomnavigation.BottomNavigationView
import eu.kanade.tachiyomi.util.system.animatorDurationScale
import eu.kanade.tachiyomi.util.view.findChild
import kotlin.math.roundToLong
/**
* Hide behavior similar to app bar for [BottomNavigationView]
*/
class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
context: Context? = null,
attrs: AttributeSet? = null,
) : CoordinatorLayout.Behavior<BottomNavigationView>(context, attrs) {
@ViewCompat.NestedScrollType
private var lastStartedType: Int = 0
private var offsetAnimator: ValueAnimator? = null
private var dyRatio = 1F
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView, dependency: View): Boolean {
return dependency is AppBarLayout
}
override fun onDependentViewChanged(
parent: CoordinatorLayout,
child: BottomNavigationView,
dependency: View,
): Boolean {
val toolbarSize = (dependency as ViewGroup).findChild<Toolbar>()?.height ?: 0
dyRatio = if (toolbarSize > 0) {
child.height.toFloat() / toolbarSize
} else {
1F
}
return false
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
directTargetChild: View,
target: View,
axes: Int,
type: Int,
): Boolean {
if (axes != ViewCompat.SCROLL_AXIS_VERTICAL) {
return false
}
lastStartedType = type
offsetAnimator?.cancel()
return true
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int,
) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat())
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: BottomNavigationView,
target: View,
type: Int,
) {
if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) {
animateBottomNavigationVisibility(child, child.translationY < child.height / 2)
}
}
private fun animateBottomNavigationVisibility(child: BottomNavigationView, isVisible: Boolean) {
offsetAnimator?.cancel()
offsetAnimator = ValueAnimator().apply {
interpolator = DecelerateInterpolator()
duration = (150 * child.context.animatorDurationScale).roundToLong()
addUpdateListener {
child.translationY = it.animatedValue as Float
}
}
offsetAnimator?.setFloatValues(
child.translationY,
if (isVisible) 0F else child.height.toFloat(),
)
offsetAnimator?.start()
}
}

View file

@ -77,7 +77,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="bottom" android:layout_gravity="bottom"
android:clickable="true" android:clickable="true"
app:layout_behavior="eu.kanade.tachiyomi.widget.HideBottomNavigationOnScrollBehavior"
app:layout_insetEdge="bottom" app:layout_insetEdge="bottom"
app:menu="@menu/main_nav" app:menu="@menu/main_nav"
tools:ignore="KeyboardInaccessibleWidget" /> tools:ignore="KeyboardInaccessibleWidget" />