Pin navigation ui option #851

This commit is contained in:
Koitharu
2024-04-23 11:35:44 +03:00
parent 3affec0f88
commit 19da2267d6
8 changed files with 62 additions and 4 deletions

View File

@@ -74,6 +74,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
val isNavLabelsVisible: Boolean
get() = prefs.getBoolean(KEY_NAV_LABELS, true)
val isNavBarPinned: Boolean
get() = prefs.getBoolean(KEY_NAV_PINNED, false)
var gridSize: Int
get() = prefs.getInt(KEY_GRID_SIZE, 100)
set(value) = prefs.edit { putInt(KEY_GRID_SIZE, value) }
@@ -653,6 +656,7 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
const val KEY_RELATED_MANGA = "related_manga"
const val KEY_NAV_MAIN = "nav_main"
const val KEY_NAV_LABELS = "nav_labels"
const val KEY_NAV_PINNED = "nav_pinned"
const val KEY_32BIT_COLOR = "enhanced_colors"
const val KEY_SOURCES_ORDER = "sources_sort_order"
const val KEY_SOURCES_CATALOG = "sources_catalog"

View File

@@ -25,6 +25,15 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
private var dyRatio = 1F
var isPinned: Boolean = false
set(value) {
field = value
if (value) {
offsetAnimator?.cancel()
offsetAnimator = null
}
}
override fun layoutDependsOn(parent: CoordinatorLayout, child: BottomNavigationView, dependency: View): Boolean {
return dependency is AppBarLayout
}
@@ -51,7 +60,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
axes: Int,
type: Int,
): Boolean {
if (axes != ViewCompat.SCROLL_AXIS_VERTICAL) {
if (isPinned || axes != ViewCompat.SCROLL_AXIS_VERTICAL) {
return false
}
lastStartedType = type
@@ -69,7 +78,9 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
type: Int,
) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat())
if (!isPinned) {
child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat())
}
}
override fun onStopNestedScroll(
@@ -78,7 +89,7 @@ class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
target: View,
type: Int,
) {
if (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH) {
if (!isPinned && (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH)) {
animateBottomNavigationVisibility(child, child.translationY < child.height / 2)
}
}

View File

@@ -38,6 +38,15 @@ class SlidingBottomNavigationView @JvmOverloads constructor(
private var currentState = STATE_UP
private var behavior = HideBottomNavigationOnScrollBehavior()
var isPinned: Boolean
get() = behavior.isPinned
set(value) {
behavior.isPinned = value
if (value) {
translationX = 0f
}
}
override fun getBehavior(): CoordinatorLayout.Behavior<*> {
return behavior
}

View File

@@ -13,6 +13,7 @@ import androidx.appcompat.view.ActionMode
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.graphics.Insets
import androidx.core.view.children
import androidx.core.view.inputmethod.EditorInfoCompat
import androidx.core.view.isInvisible
import androidx.core.view.isVisible
@@ -131,6 +132,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
viewModel.onFirstStart.observeEvent(this) {
WelcomeSheet.show(supportFragmentManager)
}
viewModel.isBottomNavPinned.observe(this, ::setNavbarPinned)
searchSuggestionViewModel.isIncognitoModeEnabled.observe(this, this::onIncognitoModeChanged)
}
@@ -399,6 +401,22 @@ class MainActivity : BaseActivity<ActivityMainBinding>(), AppBarOwner, BottomNav
}
}
private fun setNavbarPinned(isPinned: Boolean) {
viewBinding.bottomNav?.isPinned = isPinned
for (view in viewBinding.appbar.children) {
val lp = view.layoutParams as? AppBarLayout.LayoutParams ?: continue
val scrollFlags = if (isPinned) {
lp.scrollFlags and SCROLL_FLAG_SCROLL.inv()
} else {
lp.scrollFlags or SCROLL_FLAG_SCROLL
}
if (scrollFlags != lp.scrollFlags) {
lp.scrollFlags = scrollFlags
view.layoutParams = lp
}
}
}
private inner class CloseSearchCallback : OnBackPressedCallback(false) {
override fun handleOnBackPressed() {

View File

@@ -4,11 +4,13 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.plus
import org.koitharu.kotatsu.core.exceptions.EmptyHistoryException
import org.koitharu.kotatsu.core.github.AppUpdateRepository
import org.koitharu.kotatsu.core.prefs.AppSettings
import org.koitharu.kotatsu.core.prefs.observeAsFlow
import org.koitharu.kotatsu.core.ui.BaseViewModel
import org.koitharu.kotatsu.core.util.ext.MutableEventFlow
import org.koitharu.kotatsu.core.util.ext.call
@@ -46,6 +48,12 @@ class MainViewModel @Inject constructor(
.withErrorHandling()
.stateIn(viewModelScope + Dispatchers.Default, SharingStarted.Lazily, 0)
val isBottomNavPinned = settings.observeAsFlow(
AppSettings.KEY_NAV_PINNED,
) {
isNavBarPinned
}.flowOn(Dispatchers.Default)
init {
launchJob {
appUpdateRepository.fetchUpdate()

View File

@@ -19,7 +19,7 @@
android:orientation="vertical"
android:paddingVertical="@dimen/list_spacing_normal"
app:bubbleSize="small"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layoutManager=".core.ui.list.FitHeightLinearLayoutManager"
tools:listitem="@layout/item_feed" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -634,4 +634,6 @@
<string name="more_frequently">More frequently</string>
<string name="frequency_of_check">Frequency of check</string>
<string name="new_chapters_pattern">%1$s: %2$d</string>
<string name="pin_navigation_ui">Pin navigation UI</string>
<string name="pin_navigation_ui_summary">Do not hide navgation bar and search view on scroll</string>
</resources>

View File

@@ -76,6 +76,12 @@
android:key="nav_labels"
android:title="@string/show_labels_in_navbar" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="nav_pinned"
android:summary="@string/pin_navigation_ui_summary"
android:title="@string/pin_navigation_ui" />
<org.koitharu.kotatsu.settings.utils.ActivityListPreference
android:key="app_locale"
android:title="@string/language" />