Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@ class AppSettings @Inject constructor(@ApplicationContext context: Context) {
get() = prefs.getBoolean(KEY_ALL_FAVOURITES_VISIBLE, true)
set(value) = prefs.edit { putBoolean(KEY_ALL_FAVOURITES_VISIBLE, value) }

val usePillNavigation: Boolean
get() = prefs.getBoolean("use_pill_navigation", true)

val isTrackerEnabled: Boolean
get() = prefs.getBoolean(KEY_TRACKER_ENABLED, true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum class ColorScheme(
@StringRes val titleResId: Int,
) {

ONYX_GOLD(R.style.ThemeOverlay_Futon_OnyxGold, R.string.theme_name_onyx_gold),
DEFAULT(R.style.ThemeOverlay_Futon_Totoro, R.string.theme_name_totoro),
MONET(R.style.ThemeOverlay_Futon_Monet, R.string.theme_name_dynamic),
EXPRESSIVE(R.style.ThemeOverlay_Futon_Expressive, R.string.theme_name_expressive),
Expand All @@ -32,7 +33,7 @@ enum class ColorScheme(
get() = if (DynamicColors.isDynamicColorAvailable()) {
MONET
} else {
DEFAULT
ONYX_GOLD
}

fun getAvailableList(): List<ColorScheme> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,105 +8,104 @@ import android.view.animation.DecelerateInterpolator
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.ViewCompat
import com.google.android.material.appbar.AppBarLayout
import com.google.android.material.navigation.NavigationBarView
import io.github.landwarderer.futon.R
import io.github.landwarderer.futon.core.util.ext.getAnimationDuration
import io.github.landwarderer.futon.core.util.ext.measureHeight

class HideBottomNavigationOnScrollBehavior @JvmOverloads constructor(
context: Context? = null,
attrs: AttributeSet? = null,
) : CoordinatorLayout.Behavior<NavigationBarView>(context, attrs) {
context: Context? = null,
attrs: AttributeSet? = null,
) : CoordinatorLayout.Behavior<View>(context, attrs) {

@ViewCompat.NestedScrollType
private var lastStartedType: Int = 0
@ViewCompat.NestedScrollType
private var lastStartedType: Int = 0

private var offsetAnimator: ValueAnimator? = null
private var offsetAnimator: ValueAnimator? = null

private var dyRatio = 1F
private var dyRatio = 1F

var isPinned: Boolean = false
set(value) {
field = value
if (value) {
offsetAnimator?.cancel()
offsetAnimator = null
}
}
var isPinned: Boolean = false
set(value) {
field = value
if (value) {
offsetAnimator?.cancel()
offsetAnimator = null
}
}

override fun layoutDependsOn(parent: CoordinatorLayout, child: NavigationBarView, dependency: View): Boolean {
return dependency is AppBarLayout
}
override fun layoutDependsOn(parent: CoordinatorLayout, child: View, dependency: View): Boolean {
return dependency is AppBarLayout
}

override fun onDependentViewChanged(
parent: CoordinatorLayout,
child: NavigationBarView,
dependency: View,
): Boolean {
val appBarSize = dependency.measureHeight()
dyRatio = if (appBarSize > 0) {
child.measureHeight().toFloat() / appBarSize
} else {
1F
}
return false
}
override fun onDependentViewChanged(
parent: CoordinatorLayout,
child: View,
dependency: View,
): Boolean {
val appBarSize = dependency.measureHeight()
dyRatio = if (appBarSize > 0) {
child.measureHeight().toFloat() / appBarSize
} else {
1F
}
return false
}

override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: NavigationBarView,
directTargetChild: View,
target: View,
axes: Int,
type: Int,
): Boolean {
if (isPinned || axes != ViewCompat.SCROLL_AXIS_VERTICAL) {
return false
}
lastStartedType = type
offsetAnimator?.cancel()
return true
}
override fun onStartNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: View,
directTargetChild: View,
target: View,
axes: Int,
type: Int,
): Boolean {
if (isPinned || axes != ViewCompat.SCROLL_AXIS_VERTICAL) {
return false
}
lastStartedType = type
offsetAnimator?.cancel()
return true
}

override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: NavigationBarView,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int,
) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
if (!isPinned) {
child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat())
}
}
override fun onNestedPreScroll(
coordinatorLayout: CoordinatorLayout,
child: View,
target: View,
dx: Int,
dy: Int,
consumed: IntArray,
type: Int,
) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
if (!isPinned) {
child.translationY = (child.translationY + (dy * dyRatio)).coerceIn(0F, child.height.toFloat())
}
}

override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: NavigationBarView,
target: View,
type: Int,
) {
if (!isPinned && (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH)) {
animateBottomNavigationVisibility(child, child.translationY < child.height / 2)
}
}
override fun onStopNestedScroll(
coordinatorLayout: CoordinatorLayout,
child: View,
target: View,
type: Int,
) {
if (!isPinned && (lastStartedType == ViewCompat.TYPE_TOUCH || type == ViewCompat.TYPE_NON_TOUCH)) {
animateBottomNavigationVisibility(child, child.translationY < child.height / 2)
}
}

private fun animateBottomNavigationVisibility(child: NavigationBarView, isVisible: Boolean) {
offsetAnimator?.cancel()
offsetAnimator = ValueAnimator().apply {
interpolator = DecelerateInterpolator()
duration = child.context.getAnimationDuration(R.integer.config_shorterAnimTime)
addUpdateListener {
child.translationY = it.animatedValue as Float
}
}
offsetAnimator?.setFloatValues(
child.translationY,
if (isVisible) 0F else child.height.toFloat(),
)
offsetAnimator?.start()
}
private fun animateBottomNavigationVisibility(child: View, isVisible: Boolean) {
offsetAnimator?.cancel()
offsetAnimator = ValueAnimator().apply {
interpolator = DecelerateInterpolator()
duration = child.context.getAnimationDuration(R.integer.config_shorterAnimTime)
addUpdateListener {
child.translationY = it.animatedValue as Float
}
}
offsetAnimator?.setFloatValues(
child.translationY,
if (isVisible) 0F else child.height.toFloat(),
)
offsetAnimator?.start()
}
}
Loading
Loading