Pin navigation ui option #851
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user