mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-20 04:29:18 +01:00
Initial tablet NavigationRailView implementation
Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
parent
3dce788c94
commit
d82d738f38
@ -0,0 +1,50 @@
|
||||
package eu.kanade.tachiyomi.ui.base.controller
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
|
||||
/**
|
||||
* A variation of [FadeChangeHandler] that only fades in.
|
||||
*/
|
||||
class OneWayFadeChangeHandler : FadeChangeHandler {
|
||||
constructor()
|
||||
constructor(removesFromViewOnPush: Boolean) : super(removesFromViewOnPush)
|
||||
constructor(duration: Long) : super(duration)
|
||||
constructor(duration: Long, removesFromViewOnPush: Boolean) : super(
|
||||
duration,
|
||||
removesFromViewOnPush
|
||||
)
|
||||
|
||||
override fun getAnimator(
|
||||
container: ViewGroup,
|
||||
from: View?,
|
||||
to: View?,
|
||||
isPush: Boolean,
|
||||
toAddedToContainer: Boolean
|
||||
): Animator {
|
||||
val animator = AnimatorSet()
|
||||
if (to != null) {
|
||||
val start: Float = if (toAddedToContainer) 0F else to.alpha
|
||||
animator.play(ObjectAnimator.ofFloat(to, View.ALPHA, start, 1f))
|
||||
}
|
||||
|
||||
if (from != null && (!isPush || removesFromViewOnPush())) {
|
||||
if (!container.context.isTablet()) {
|
||||
animator.play(ObjectAnimator.ofFloat(from, View.ALPHA, 0f))
|
||||
} else {
|
||||
container.removeView(from)
|
||||
}
|
||||
}
|
||||
return animator
|
||||
}
|
||||
|
||||
override fun copy(): ControllerChangeHandler {
|
||||
return OneWayFadeChangeHandler(animationDuration, removesFromViewOnPush())
|
||||
}
|
||||
}
|
@ -91,10 +91,10 @@ class ExtensionBottomSheet @JvmOverloads constructor(context: Context, attrs: At
|
||||
binding.pager.adapter = TabbedSheetAdapter()
|
||||
binding.tabs.setupWithViewPager(binding.pager)
|
||||
this.controller = controller
|
||||
binding.pager.doOnApplyWindowInsets { _, _, _ ->
|
||||
binding.pager.doOnApplyWindowInsets { _, insets, _ ->
|
||||
val bottomBar = controller.activityBinding?.bottomNav
|
||||
extensionFrameLayout?.binding?.recycler?.updatePaddingRelative(bottom = bottomBar?.height ?: 0)
|
||||
migrationFrameLayout?.binding?.recycler?.updatePaddingRelative(bottom = bottomBar?.height ?: 0)
|
||||
extensionFrameLayout?.binding?.recycler?.updatePaddingRelative(bottom = bottomBar?.height ?: insets.systemWindowInsetBottom)
|
||||
migrationFrameLayout?.binding?.recycler?.updatePaddingRelative(bottom = bottomBar?.height ?: insets.systemWindowInsetBottom)
|
||||
}
|
||||
binding.tabs.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||
@ -336,9 +336,15 @@ class ExtensionBottomSheet @JvmOverloads constructor(context: Context, attrs: At
|
||||
* @return a new view.
|
||||
*/
|
||||
override fun createView(container: ViewGroup): View {
|
||||
val binding = RecyclerWithScrollerBinding.inflate(LayoutInflater.from(container.context), container, false)
|
||||
val binding = RecyclerWithScrollerBinding.inflate(
|
||||
LayoutInflater.from(container.context),
|
||||
container,
|
||||
false
|
||||
)
|
||||
val view: RecyclerWithScrollerView = binding.root
|
||||
view.setUp(this@ExtensionBottomSheet, binding, this@ExtensionBottomSheet.controller.activityBinding?.bottomNav?.height ?: 0)
|
||||
val height = this@ExtensionBottomSheet.controller.activityBinding?.bottomNav?.height
|
||||
?: view.rootWindowInsets?.systemWindowInsetBottom ?: 0
|
||||
view.setUp(this@ExtensionBottomSheet, binding, height)
|
||||
|
||||
return view
|
||||
}
|
||||
|
@ -200,6 +200,10 @@ class LibraryController(
|
||||
get() = preferences.showCategoryInTitle().get() && presenter.showAllCategories
|
||||
private lateinit var elevateAppBar: ((Boolean) -> Unit)
|
||||
private var hopperOffset = 0f
|
||||
private val maxHopperOffset: Float
|
||||
get() =
|
||||
if (activityBinding?.bottomNav != null) 55f.dpToPx
|
||||
else (view?.rootWindowInsets?.systemWindowInsetBottom?.toFloat() ?: 0f) + 55f.dpToPx
|
||||
|
||||
override fun getTitle(): String? {
|
||||
setSubtitle()
|
||||
@ -222,9 +226,9 @@ class LibraryController(
|
||||
if (!recyclerCover.isClickable && isAnimatingHopper != true) {
|
||||
if (preferences.autohideHopper().get()) {
|
||||
hopperOffset += dy
|
||||
hopperOffset = hopperOffset.coerceIn(0f, 55f.dpToPx)
|
||||
hopperOffset = hopperOffset.coerceIn(0f, maxHopperOffset)
|
||||
}
|
||||
if (!preferences.hideBottomNavOnScroll().get()) {
|
||||
if (!preferences.hideBottomNavOnScroll().get() || activityBinding?.bottomNav == null) {
|
||||
updateFilterSheetY()
|
||||
}
|
||||
binding.roundedCategoryHopper.upCategory.alpha = if (isAtTop()) 0.25f else 1f
|
||||
@ -291,6 +295,11 @@ class LibraryController(
|
||||
binding.fastScroller.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
bottomMargin = -pad.toInt()
|
||||
}
|
||||
} else {
|
||||
binding.filterBottomSheet.filterBottomSheet.updatePaddingRelative(
|
||||
bottom = view?.rootWindowInsets?.getBottomGestureInsets() ?: 0
|
||||
)
|
||||
updateHopperY()
|
||||
}
|
||||
}
|
||||
|
||||
@ -300,12 +309,17 @@ class LibraryController(
|
||||
) ?: 0
|
||||
if (preferences.autohideHopper().get()) {
|
||||
// Flow same snap rules as bottom nav
|
||||
val closerToHopperBottom = hopperOffset > 25f.dpToPx
|
||||
val closerToHopperBottom = hopperOffset > maxHopperOffset / 2
|
||||
val halfWayBottom = activityBinding?.bottomNav?.height?.toFloat()?.div(2) ?: 0f
|
||||
val closerToBottom = (activityBinding?.bottomNav?.translationY ?: 0f) > halfWayBottom
|
||||
val atTop = !binding.libraryGridRecycler.recycler.canScrollVertically(-1)
|
||||
val closerToEdge = if (preferences.hideBottomNavOnScroll().get()) (closerToBottom && !atTop) else closerToHopperBottom
|
||||
val end = if (closerToEdge) 55f.dpToPx else 0f
|
||||
val closerToEdge =
|
||||
if (preferences.hideBottomNavOnScroll().get() && activityBinding?.bottomNav != null) {
|
||||
closerToBottom && !atTop
|
||||
} else {
|
||||
closerToHopperBottom
|
||||
}
|
||||
val end = if (closerToEdge) maxHopperOffset else 0f
|
||||
val alphaAnimation = ValueAnimator.ofFloat(hopperOffset, end)
|
||||
alphaAnimation.addUpdateListener { valueAnimator ->
|
||||
hopperOffset = valueAnimator.animatedValue as Float
|
||||
@ -385,7 +399,7 @@ class LibraryController(
|
||||
if (preferences.shownFilterTutorial().get() || !hasExpanded) return
|
||||
val activityBinding = activityBinding ?: return
|
||||
val activity = activity ?: return
|
||||
val icon = activityBinding.bottomNav.getItemView(R.id.nav_library) ?: return
|
||||
val icon = (activityBinding.bottomNav ?: activityBinding.sideNav)?.getItemView(R.id.nav_library) ?: return
|
||||
filterTooltip =
|
||||
ViewTooltip.on(activity, icon).autoHide(false, 0L).align(ViewTooltip.ALIGN.START)
|
||||
.position(ViewTooltip.Position.TOP).text(R.string.tap_library_to_show_filters)
|
||||
@ -684,7 +698,7 @@ class LibraryController(
|
||||
activityBinding?.bottomNav?.y ?: binding.filterBottomSheet.filterBottomSheet.y
|
||||
)
|
||||
val insetBottom = view.rootWindowInsets?.systemWindowInsetBottom ?: 0
|
||||
if (!preferences.autohideHopper().get()) {
|
||||
if (!preferences.autohideHopper().get() || activityBinding?.bottomNav == null) {
|
||||
listOfYs.add(view.height - (insetBottom).toFloat())
|
||||
}
|
||||
binding.categoryHopperFrame.y = -binding.categoryHopperFrame.height +
|
||||
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.ui.library.display
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import android.view.ViewTreeObserver
|
||||
import android.widget.SeekBar
|
||||
import androidx.core.animation.addListener
|
||||
@ -27,6 +28,7 @@ import kotlin.math.roundToInt
|
||||
class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null) :
|
||||
BaseLibraryDisplayView<LibraryDisplayLayoutBinding>(context, attrs) {
|
||||
|
||||
var mainView: View? = null
|
||||
override fun inflateBinding() = LibraryDisplayLayoutBinding.bind(this)
|
||||
override fun initGeneralPreferences() {
|
||||
binding.displayGroup.bindToPreference(preferences.libraryLayout())
|
||||
@ -127,7 +129,7 @@ class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
|
||||
private fun setGridText(progress: Int) {
|
||||
with(binding.gridSizeText) {
|
||||
val rows = this@LibraryDisplayView.rowsForValue(progress)
|
||||
val rows = (mainView ?: this@LibraryDisplayView).rowsForValue(progress)
|
||||
val titleText = context.getString(R.string.grid_size)
|
||||
val subtitleText = context.getString(R.string._per_row, rows)
|
||||
text = titleText.withSubtitle(context, subtitleText)
|
||||
@ -138,7 +140,7 @@ class LibraryDisplayView @JvmOverloads constructor(context: Context, attrs: Attr
|
||||
with(binding.seekBarTextView.root) {
|
||||
val value =
|
||||
(progress * (seekBar.width - 12.dpToPx - 2 * seekBar.thumbOffset)) / seekBar.max
|
||||
text = this@LibraryDisplayView.rowsForValue(progress).toString()
|
||||
text = (mainView ?: this@LibraryDisplayView).rowsForValue(progress).toString()
|
||||
x = seekBar.x + value + seekBar.thumbOffset / 2 + 5.dpToPx
|
||||
y = seekBar.y + binding.gridSizeLayout.y - 6.dpToPx - height
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ open class TabbedLibraryDisplaySheet(val controller: Controller) :
|
||||
badgesView.controller = libraryController
|
||||
categoryView.controller = libraryController
|
||||
}
|
||||
displayView.mainView = controller.view
|
||||
binding.menu.isVisible = controller !is SettingsLibraryController
|
||||
binding.menu.compatToolTipText = context.getString(R.string.more_library_settings)
|
||||
binding.menu.setImageDrawable(
|
||||
|
@ -110,7 +110,10 @@ class FilterBottomSheet @JvmOverloads constructor(context: Context, attrs: Attri
|
||||
this.controller = controller
|
||||
libraryRecyler = controller.binding.libraryGridRecycler.recycler
|
||||
libraryRecyler?.post {
|
||||
bottomBarHeight = controller.activityBinding?.bottomNav?.height ?: 0
|
||||
bottomBarHeight =
|
||||
controller.activityBinding?.bottomNav?.height
|
||||
?: controller.activityBinding?.root?.rootWindowInsets?.systemWindowInsetBottom
|
||||
?: 0
|
||||
}
|
||||
val shadow2: View = controller.binding.shadow2
|
||||
val shadow: View = controller.binding.shadow
|
||||
|
@ -35,6 +35,7 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.Router
|
||||
import com.getkeepsafe.taptargetview.TapTarget
|
||||
import com.getkeepsafe.taptargetview.TapTargetView
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.BuildConfig
|
||||
import eu.kanade.tachiyomi.Migrations
|
||||
@ -71,6 +72,7 @@ import eu.kanade.tachiyomi.util.system.contextCompatDrawable
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.hasSideNavBar
|
||||
import eu.kanade.tachiyomi.util.system.isBottomTappable
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.launchUI
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.doOnApplyWindowInsets
|
||||
@ -167,7 +169,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
)
|
||||
|
||||
var continueSwitchingTabs = false
|
||||
binding.bottomNav.getItemView(R.id.nav_library)?.setOnLongClickListener {
|
||||
nav.getItemView(R.id.nav_library)?.setOnLongClickListener {
|
||||
if (!LibraryUpdateService.isRunning()) {
|
||||
LibraryUpdateService.start(this)
|
||||
binding.mainContent.snack(R.string.updating_library) {
|
||||
@ -186,9 +188,9 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
true
|
||||
}
|
||||
for (id in listOf(R.id.nav_recents, R.id.nav_browse)) {
|
||||
binding.bottomNav.getItemView(id)?.setOnLongClickListener {
|
||||
binding.bottomNav.selectedItemId = id
|
||||
binding.bottomNav.post {
|
||||
nav.getItemView(id)?.setOnLongClickListener {
|
||||
nav.selectedItemId = id
|
||||
nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller as? BottomSheetController
|
||||
controller?.showSheet()
|
||||
@ -196,15 +198,67 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
true
|
||||
}
|
||||
}
|
||||
binding.bottomNav.setOnNavigationItemSelectedListener { item ->
|
||||
|
||||
val container: ViewGroup = binding.controllerContainer
|
||||
|
||||
val content: ViewGroup = binding.mainContent
|
||||
DownloadService.addListener(this)
|
||||
content.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
container.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
|
||||
supportActionBar?.setDisplayShowCustomEnabled(true)
|
||||
|
||||
setNavBarColor(content.rootWindowInsets)
|
||||
nav.isVisible = false
|
||||
content.doOnApplyWindowInsets { v, insets, _ ->
|
||||
setNavBarColor(insets)
|
||||
val contextView = window?.decorView?.findViewById<View>(R.id.action_mode_bar)
|
||||
contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
leftMargin = insets.systemWindowInsetLeft
|
||||
rightMargin = insets.systemWindowInsetRight
|
||||
}
|
||||
// Consume any horizontal insets and pad all content in. There's not much we can do
|
||||
// with horizontal insets
|
||||
v.updatePadding(
|
||||
left = insets.systemWindowInsetLeft,
|
||||
right = insets.systemWindowInsetRight
|
||||
)
|
||||
binding.appBar.updatePadding(
|
||||
top = insets.systemWindowInsetTop
|
||||
)
|
||||
binding.bottomNav?.updatePadding(bottom = insets.systemWindowInsetBottom)
|
||||
binding.sideNav?.updatePadding(
|
||||
left = insets.systemWindowInsetLeft,
|
||||
right = insets.systemWindowInsetRight
|
||||
)
|
||||
binding.bottomView?.isVisible = insets.systemWindowInsetBottom > 0
|
||||
binding.bottomView?.updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
height = insets.systemWindowInsetBottom
|
||||
}
|
||||
}
|
||||
|
||||
router = Conductor.attachRouter(this, container, savedInstanceState)
|
||||
|
||||
if (router.hasRootController()) {
|
||||
nav.selectedItemId =
|
||||
when (router.backstack.firstOrNull()?.controller) {
|
||||
is RecentsController -> R.id.nav_recents
|
||||
is BrowseController -> R.id.nav_browse
|
||||
else -> R.id.nav_library
|
||||
}
|
||||
}
|
||||
|
||||
nav.setOnItemSelectedListener { item ->
|
||||
val id = item.itemId
|
||||
val currentController = router.backstack.lastOrNull()?.controller
|
||||
if (!continueSwitchingTabs && currentController is BottomNavBarInterface) {
|
||||
if (!currentController.canChangeTabs {
|
||||
continueSwitchingTabs = true
|
||||
this@MainActivity.binding.bottomNav.selectedItemId = id
|
||||
this@MainActivity.nav.selectedItemId = id
|
||||
}
|
||||
) return@setOnNavigationItemSelectedListener false
|
||||
) return@setOnItemSelectedListener false
|
||||
}
|
||||
continueSwitchingTabs = false
|
||||
val currentRoot = router.backstack.firstOrNull()
|
||||
@ -226,43 +280,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
}
|
||||
true
|
||||
}
|
||||
val container: ViewGroup = binding.controllerContainer
|
||||
|
||||
val content: ViewGroup = binding.mainContent
|
||||
DownloadService.addListener(this)
|
||||
content.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
container.systemUiVisibility =
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
|
||||
|
||||
supportActionBar?.setDisplayShowCustomEnabled(true)
|
||||
|
||||
setNavBarColor(content.rootWindowInsets)
|
||||
binding.bottomView.isVisible = false
|
||||
content.doOnApplyWindowInsets { v, insets, _ ->
|
||||
setNavBarColor(insets)
|
||||
val contextView = window?.decorView?.findViewById<View>(R.id.action_mode_bar)
|
||||
contextView?.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
leftMargin = insets.systemWindowInsetLeft
|
||||
rightMargin = insets.systemWindowInsetRight
|
||||
}
|
||||
// Consume any horizontal insets and pad all content in. There's not much we can do
|
||||
// with horizontal insets
|
||||
v.updatePadding(
|
||||
left = insets.systemWindowInsetLeft,
|
||||
right = insets.systemWindowInsetRight
|
||||
)
|
||||
binding.appBar.updatePadding(
|
||||
top = insets.systemWindowInsetTop
|
||||
)
|
||||
binding.bottomNav.updatePadding(bottom = insets.systemWindowInsetBottom)
|
||||
binding.bottomView.isVisible = insets.systemWindowInsetBottom > 0
|
||||
binding.bottomView.updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
height = insets.systemWindowInsetBottom
|
||||
}
|
||||
}
|
||||
|
||||
router = Conductor.attachRouter(this, container, savedInstanceState)
|
||||
if (!router.hasRootController()) {
|
||||
// Set start screen
|
||||
if (!handleIntentAction(intent)) {
|
||||
@ -288,9 +306,9 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
binding.cardToolbar.menu.findItem(R.id.action_search)?.expandActionView()
|
||||
}
|
||||
|
||||
binding.bottomNav.isVisible = !hideBottomNav
|
||||
binding.bottomView.visibility = if (hideBottomNav) View.GONE else binding.bottomView.visibility
|
||||
binding.bottomNav.alpha = if (hideBottomNav) 0f else 1f
|
||||
nav.isVisible = !hideBottomNav
|
||||
binding.bottomView?.visibility = if (hideBottomNav) View.GONE else binding.bottomView?.visibility ?: View.GONE
|
||||
nav.alpha = if (hideBottomNav) 0f else 1f
|
||||
router.addChangeListener(
|
||||
object : ControllerChangeHandler.ControllerChangeListener {
|
||||
override fun onChangeStarted(
|
||||
@ -303,7 +321,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
syncActivityViewWithController(to, from, isPush)
|
||||
binding.appBar.y = 0f
|
||||
if (!isPush || router.backstackSize == 1) {
|
||||
binding.bottomNav.translationY = 0f
|
||||
nav.translationY = 0f
|
||||
}
|
||||
snackBar?.dismiss()
|
||||
}
|
||||
@ -316,7 +334,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
handler: ControllerChangeHandler
|
||||
) {
|
||||
binding.appBar.y = 0f
|
||||
binding.bottomNav.translationY = 0f
|
||||
nav.translationY = 0f
|
||||
showDLQueueTutorial()
|
||||
}
|
||||
}
|
||||
@ -348,10 +366,10 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
binding.cardToolbar.setIncognitoMode(it)
|
||||
}
|
||||
setExtensionsBadge()
|
||||
setFloatingToolbar(canShowFloatingToolbar(router.backstack.lastOrNull()?.controller))
|
||||
setFloatingToolbar(canShowFloatingToolbar(router.backstack.lastOrNull()?.controller), changeBG = false)
|
||||
}
|
||||
|
||||
open fun setFloatingToolbar(show: Boolean, solidBG: Boolean = false) {
|
||||
open fun setFloatingToolbar(show: Boolean, solidBG: Boolean = false, changeBG: Boolean = true) {
|
||||
val oldTB = currentToolbar
|
||||
currentToolbar = if (show) {
|
||||
binding.cardToolbar
|
||||
@ -363,9 +381,11 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
}
|
||||
binding.toolbar.isVisible = !show
|
||||
binding.cardFrame.isVisible = show
|
||||
binding.appBar.setBackgroundColor(
|
||||
if (show && !solidBG) Color.TRANSPARENT else getResourceColor(R.attr.colorSecondary)
|
||||
)
|
||||
if (changeBG) {
|
||||
binding.appBar.setBackgroundColor(
|
||||
if (show && !solidBG) Color.TRANSPARENT else getResourceColor(R.attr.colorSecondary)
|
||||
)
|
||||
}
|
||||
currentToolbar?.setNavigationOnClickListener {
|
||||
val rootSearchController = router.backstack.lastOrNull()?.controller
|
||||
if (rootSearchController is RootSearchInterface) {
|
||||
@ -435,10 +455,10 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
private fun setExtensionsBadge() {
|
||||
val updates = preferences.extensionUpdatesCount().getOrDefault()
|
||||
if (updates > 0) {
|
||||
val badge = binding.bottomNav.getOrCreateBadge(R.id.nav_browse)
|
||||
val badge = nav.getOrCreateBadge(R.id.nav_browse)
|
||||
badge.number = updates
|
||||
} else {
|
||||
binding.bottomNav.removeBadge(R.id.nav_browse)
|
||||
nav.removeBadge(R.id.nav_browse)
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +475,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
downloadManager.hasQueue() && !preferences.shownDownloadQueueTutorial().get()
|
||||
) {
|
||||
if (!isBindingInitialized) return
|
||||
val recentsItem = binding.bottomNav.getItemView(R.id.nav_recents) ?: return
|
||||
val recentsItem = nav.getItemView(R.id.nav_recents) ?: return
|
||||
preferences.shownDownloadQueueTutorial().set(true)
|
||||
TapTargetView.showFor(
|
||||
this,
|
||||
@ -474,7 +494,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
object : TapTargetView.Listener() {
|
||||
override fun onTargetClick(view: TapTargetView) {
|
||||
super.onTargetClick(view)
|
||||
binding.bottomNav.selectedItemId = R.id.nav_recents
|
||||
nav.selectedItemId = R.id.nav_recents
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -540,14 +560,14 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
intent.getIntExtra("groupId", 0)
|
||||
)
|
||||
when (intent.action) {
|
||||
SHORTCUT_LIBRARY -> binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
SHORTCUT_LIBRARY -> nav.selectedItemId = R.id.nav_library
|
||||
SHORTCUT_RECENTLY_UPDATED, SHORTCUT_RECENTLY_READ -> {
|
||||
if (binding.bottomNav.selectedItemId != R.id.nav_recents) {
|
||||
binding.bottomNav.selectedItemId = R.id.nav_recents
|
||||
if (nav.selectedItemId != R.id.nav_recents) {
|
||||
nav.selectedItemId = R.id.nav_recents
|
||||
} else {
|
||||
router.popToRoot()
|
||||
}
|
||||
binding.bottomNav.post {
|
||||
nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller as? RecentsController
|
||||
controller?.tempJumpTo(
|
||||
@ -558,14 +578,14 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
)
|
||||
}
|
||||
}
|
||||
SHORTCUT_BROWSE -> binding.bottomNav.selectedItemId = R.id.nav_browse
|
||||
SHORTCUT_BROWSE -> nav.selectedItemId = R.id.nav_browse
|
||||
SHORTCUT_EXTENSIONS -> {
|
||||
if (binding.bottomNav.selectedItemId != R.id.nav_browse) {
|
||||
binding.bottomNav.selectedItemId = R.id.nav_browse
|
||||
if (nav.selectedItemId != R.id.nav_browse) {
|
||||
nav.selectedItemId = R.id.nav_browse
|
||||
} else {
|
||||
router.popToRoot()
|
||||
}
|
||||
binding.bottomNav.post {
|
||||
nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller as? BrowseController
|
||||
controller?.showSheet()
|
||||
@ -573,25 +593,25 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
}
|
||||
SHORTCUT_MANGA -> {
|
||||
val extras = intent.extras ?: return false
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
if (router.backstack.isEmpty()) nav.selectedItemId = R.id.nav_library
|
||||
router.pushController(MangaDetailsController(extras).withFadeTransaction())
|
||||
}
|
||||
SHORTCUT_UPDATE_NOTES -> {
|
||||
val extras = intent.extras ?: return false
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
if (router.backstack.isEmpty()) nav.selectedItemId = R.id.nav_library
|
||||
if (router.backstack.lastOrNull()?.controller !is AboutController.NewUpdateDialogController) {
|
||||
AboutController.NewUpdateDialogController(extras).showDialog(router)
|
||||
}
|
||||
}
|
||||
SHORTCUT_SOURCE -> {
|
||||
val extras = intent.extras ?: return false
|
||||
if (router.backstack.isEmpty()) binding.bottomNav.selectedItemId = R.id.nav_library
|
||||
if (router.backstack.isEmpty()) nav.selectedItemId = R.id.nav_library
|
||||
router.pushController(BrowseSourceController(extras).withFadeTransaction())
|
||||
}
|
||||
SHORTCUT_DOWNLOADS -> {
|
||||
binding.bottomNav.selectedItemId = R.id.nav_recents
|
||||
nav.selectedItemId = R.id.nav_recents
|
||||
router.popToRoot()
|
||||
binding.bottomNav.post {
|
||||
nav.post {
|
||||
val controller =
|
||||
router.backstack.firstOrNull()?.controller as? RecentsController
|
||||
controller?.showSheet()
|
||||
@ -619,7 +639,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
else !router.handleBack()
|
||||
) {
|
||||
if (preferences.backReturnsToStart().get() && this !is SearchActivity &&
|
||||
startingTab() != binding.bottomNav.selectedItemId
|
||||
startingTab() != nav.selectedItemId
|
||||
) {
|
||||
goToStartingTab()
|
||||
} else {
|
||||
@ -633,13 +653,16 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
}
|
||||
}
|
||||
|
||||
protected val nav: NavigationBarView
|
||||
get() = binding.bottomNav ?: binding.sideNav!!
|
||||
|
||||
private fun setStartingTab() {
|
||||
if (this is SearchActivity) return
|
||||
if (binding.bottomNav.selectedItemId != R.id.nav_browse &&
|
||||
if (nav.selectedItemId != R.id.nav_browse &&
|
||||
preferences.startingTab().get() >= 0
|
||||
) {
|
||||
preferences.startingTab().set(
|
||||
when (binding.bottomNav.selectedItemId) {
|
||||
when (nav.selectedItemId) {
|
||||
R.id.nav_library -> 0
|
||||
else -> 1
|
||||
}
|
||||
@ -658,7 +681,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
}
|
||||
|
||||
private fun goToStartingTab() {
|
||||
binding.bottomNav.selectedItemId = startingTab()
|
||||
nav.selectedItemId = startingTab()
|
||||
}
|
||||
|
||||
private fun setRoot(controller: Controller, id: Int) {
|
||||
@ -750,27 +773,33 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
binding.cardToolbar.subtitle = null
|
||||
drawerArrow?.progress = 1f
|
||||
|
||||
binding.bottomNav.visibility = if (!hideBottomNav) View.VISIBLE else binding.bottomNav.visibility
|
||||
animationSet?.cancel()
|
||||
animationSet = AnimatorSet()
|
||||
val alphaAnimation = ValueAnimator.ofFloat(
|
||||
binding.bottomNav.alpha,
|
||||
if (hideBottomNav) 0f else 1f
|
||||
)
|
||||
alphaAnimation.addUpdateListener { valueAnimator ->
|
||||
binding.bottomNav.alpha = valueAnimator.animatedValue as Float
|
||||
}
|
||||
alphaAnimation.addListener(
|
||||
EndAnimatorListener {
|
||||
binding.bottomNav.isVisible = !hideBottomNav
|
||||
binding.bottomView.visibility =
|
||||
if (hideBottomNav) View.GONE else binding.bottomView.visibility
|
||||
nav.visibility = if (!hideBottomNav) View.VISIBLE else nav.visibility
|
||||
if (isTablet()) {
|
||||
nav.isVisible = !hideBottomNav
|
||||
nav.alpha = 1f
|
||||
} else {
|
||||
animationSet?.cancel()
|
||||
animationSet = AnimatorSet()
|
||||
val alphaAnimation = ValueAnimator.ofFloat(
|
||||
nav.alpha,
|
||||
if (hideBottomNav) 0f else 1f
|
||||
)
|
||||
alphaAnimation.addUpdateListener { valueAnimator ->
|
||||
nav.alpha = valueAnimator.animatedValue as Float
|
||||
}
|
||||
)
|
||||
alphaAnimation.duration = 200
|
||||
alphaAnimation.startDelay = 50
|
||||
animationSet?.playTogether(alphaAnimation)
|
||||
animationSet?.start()
|
||||
alphaAnimation.addListener(
|
||||
EndAnimatorListener {
|
||||
nav.isVisible = !hideBottomNav
|
||||
binding.bottomView?.visibility =
|
||||
if (hideBottomNav) View.GONE else binding.bottomView?.visibility
|
||||
?: View.GONE
|
||||
}
|
||||
)
|
||||
alphaAnimation.duration = 200
|
||||
alphaAnimation.startDelay = 50
|
||||
animationSet?.playTogether(alphaAnimation)
|
||||
animationSet?.start()
|
||||
}
|
||||
}
|
||||
|
||||
fun showTabBar(show: Boolean, animate: Boolean = true) {
|
||||
@ -810,10 +839,10 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
val hasQueue = downloading || downloadManager.hasQueue()
|
||||
launchUI {
|
||||
if (hasQueue) {
|
||||
binding.bottomNav.getOrCreateBadge(R.id.nav_recents)
|
||||
nav.getOrCreateBadge(R.id.nav_recents)
|
||||
showDLQueueTutorial()
|
||||
} else {
|
||||
binding.bottomNav.removeBadge(R.id.nav_recents)
|
||||
nav.removeBadge(R.id.nav_recents)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -867,7 +896,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
|
||||
val diffX = e2.x - e1.x
|
||||
if (abs(diffX) <= abs(diffY)) {
|
||||
val sheetRect = Rect()
|
||||
binding.bottomNav.getGlobalVisibleRect(sheetRect)
|
||||
binding.bottomNav?.getGlobalVisibleRect(sheetRect)
|
||||
if (sheetRect.contains(e1.x.toInt(), e1.y.toInt()) &&
|
||||
abs(diffY) > Companion.SWIPE_THRESHOLD &&
|
||||
abs(velocityY) > Companion.SWIPE_VELOCITY_THRESHOLD &&
|
||||
|
@ -51,8 +51,8 @@ class SearchActivity : MainActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun setFloatingToolbar(show: Boolean, solidBG: Boolean) {
|
||||
super.setFloatingToolbar(show, solidBG)
|
||||
override fun setFloatingToolbar(show: Boolean, solidBG: Boolean, changeBG: Boolean) {
|
||||
super.setFloatingToolbar(show, solidBG, changeBG)
|
||||
currentToolbar?.setNavigationOnClickListener { popToRoot() }
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@ class SearchActivity : MainActivity() {
|
||||
binding.toolbar.navigationIcon = drawerArrow
|
||||
drawerArrow?.progress = 1f
|
||||
|
||||
binding.bottomNav.isVisible = false
|
||||
binding.bottomView.isVisible = false
|
||||
nav.isVisible = false
|
||||
binding.bottomView?.isVisible = false
|
||||
}
|
||||
|
||||
override fun handleIntentAction(intent: Intent): Boolean {
|
||||
|
@ -163,11 +163,11 @@ class RecentsController(bundle: Bundle? = null) :
|
||||
height = it.systemWindowInsetTop + (toolbarHeight ?: appBarHeight)
|
||||
}
|
||||
binding.recycler.updatePaddingRelative(
|
||||
bottom = activityBinding?.bottomNav?.height ?: 0
|
||||
bottom = activityBinding?.bottomNav?.height ?: it.systemWindowInsetBottom
|
||||
)
|
||||
binding.recentsEmptyView.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = headerHeight
|
||||
bottomMargin = activityBinding?.bottomNav?.height ?: 0
|
||||
bottomMargin = activityBinding?.bottomNav?.height ?: it.systemWindowInsetBottom
|
||||
}
|
||||
},
|
||||
onBottomNavUpdate = {
|
||||
@ -182,10 +182,11 @@ class RecentsController(bundle: Bundle? = null) :
|
||||
}
|
||||
)
|
||||
|
||||
activityBinding?.bottomNav?.post {
|
||||
binding.recycler.updatePaddingRelative(bottom = activityBinding?.bottomNav?.height ?: 0)
|
||||
activityBinding?.root?.post {
|
||||
val height = activityBinding?.bottomNav?.height ?: view.rootWindowInsets?.systemWindowInsetBottom ?: 0
|
||||
binding.recycler.updatePaddingRelative(bottom = height)
|
||||
binding.downloadBottomSheet.dlRecycler.updatePaddingRelative(
|
||||
bottom = activityBinding?.bottomNav?.height ?: 0
|
||||
bottom = height
|
||||
)
|
||||
val isExpanded = binding.downloadBottomSheet.root.sheetBehavior.isExpanded()
|
||||
activityBinding?.tabsFrameLayout?.isVisible = !isExpanded
|
||||
|
@ -22,17 +22,18 @@ import com.bluelinelabs.conductor.Controller
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.databinding.MainActivityBinding
|
||||
import eu.kanade.tachiyomi.ui.base.MaterialFastScroll
|
||||
import eu.kanade.tachiyomi.ui.base.controller.OneWayFadeChangeHandler
|
||||
import eu.kanade.tachiyomi.ui.main.BottomSheetController
|
||||
import eu.kanade.tachiyomi.ui.main.FloatingSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.ui.manga.MangaDetailsController
|
||||
import eu.kanade.tachiyomi.util.system.dpToPx
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.system.isTablet
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import uy.kohesive.injekt.api.get
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
@ -171,6 +172,9 @@ fun Controller.scrollViewWith(
|
||||
var statusBarHeight = -1
|
||||
val tabBarHeight = 48.dpToPx
|
||||
activityBinding?.appBar?.y = 0f
|
||||
activityBinding?.tabsFrameLayout?.elevation = 0f
|
||||
val isTabletWithTabs = recycler.context.isTablet() && includeTabView
|
||||
activityBinding?.tabShadow?.isVisible = isTabletWithTabs
|
||||
val attrsArray = intArrayOf(R.attr.actionBarSize)
|
||||
val array = recycler.context.obtainStyledAttributes(attrsArray)
|
||||
var appBarHeight = (
|
||||
@ -226,17 +230,33 @@ fun Controller.scrollViewWith(
|
||||
liftOnScroll.invoke(el)
|
||||
} else {
|
||||
elevationAnim?.cancel()
|
||||
val floatingBar = (this as? FloatingSearchInterface)?.showFloatingBar() == true && !includeTabView
|
||||
if (isTabletWithTabs && el) {
|
||||
activityBinding?.tabShadow?.isVisible = true
|
||||
}
|
||||
val floatingBar =
|
||||
(this as? FloatingSearchInterface)?.showFloatingBar() == true && !includeTabView
|
||||
if (floatingBar) {
|
||||
activityBinding?.appBar?.elevation = 0f
|
||||
if (isTabletWithTabs) {
|
||||
activityBinding?.tabShadow?.alpha = 0f
|
||||
} else {
|
||||
activityBinding?.appBar?.elevation = 0f
|
||||
}
|
||||
return@f
|
||||
}
|
||||
elevationAnim = ValueAnimator.ofFloat(
|
||||
activityBinding?.appBar?.elevation ?: 0f,
|
||||
if (isTabletWithTabs) {
|
||||
(activityBinding?.tabShadow?.alpha ?: 0f) * 100
|
||||
} else {
|
||||
activityBinding?.appBar?.elevation ?: 0f
|
||||
},
|
||||
if (el) 15f else 0f
|
||||
)
|
||||
elevationAnim?.addUpdateListener { valueAnimator ->
|
||||
activityBinding?.appBar?.elevation = valueAnimator.animatedValue as Float
|
||||
if (isTabletWithTabs) {
|
||||
activityBinding?.tabShadow?.alpha = valueAnimator.animatedValue as Float / 100
|
||||
} else {
|
||||
activityBinding?.appBar?.elevation = valueAnimator.animatedValue as Float
|
||||
}
|
||||
}
|
||||
elevationAnim?.start()
|
||||
}
|
||||
@ -254,6 +274,7 @@ fun Controller.scrollViewWith(
|
||||
super.onChangeStart(controller, changeHandler, changeType)
|
||||
isInView = changeType.isEnter
|
||||
if (changeType.isEnter) {
|
||||
activityBinding?.tabShadow?.isVisible = isTabletWithTabs
|
||||
elevateFunc(elevate)
|
||||
if (fakeToolbarView?.parent != null) {
|
||||
val parent = fakeToolbarView?.parent as? ViewGroup ?: return
|
||||
@ -275,6 +296,7 @@ fun Controller.scrollViewWith(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
activityBinding?.tabShadow?.isVisible = false
|
||||
if (!customPadding && lastY == 0f && (
|
||||
(
|
||||
this@scrollViewWith !is FloatingSearchInterface && router.backstack.lastOrNull()
|
||||
@ -318,6 +340,7 @@ fun Controller.scrollViewWith(
|
||||
recycler.post {
|
||||
elevateFunc(recycler.canScrollVertically(-1))
|
||||
}
|
||||
val isTablet = recycler.context.isTablet()
|
||||
recycler.addOnScrollListener(
|
||||
object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
@ -336,7 +359,7 @@ fun Controller.scrollViewWith(
|
||||
.setDuration(shortAnimationDuration.toLong())
|
||||
.start()
|
||||
if (router.backstackSize == 1 && isInView) {
|
||||
activityBinding!!.bottomNav.let {
|
||||
activityBinding!!.bottomNav?.let {
|
||||
val animator = it.animate()?.translationY(0f)
|
||||
?.setDuration(shortAnimationDuration.toLong())
|
||||
animator?.setUpdateListener {
|
||||
@ -348,36 +371,43 @@ fun Controller.scrollViewWith(
|
||||
lastY = 0f
|
||||
if (elevate) elevateFunc(false)
|
||||
} else {
|
||||
activityBinding!!.appBar.y -= dy
|
||||
activityBinding!!.appBar.y = MathUtils.clamp(
|
||||
activityBinding!!.appBar.y,
|
||||
-activityBinding!!.appBar.height.toFloat(),
|
||||
0f
|
||||
)
|
||||
val tabBar = activityBinding!!.bottomNav
|
||||
if (tabBar.isVisible && isInView) {
|
||||
if (preferences.hideBottomNavOnScroll().get()) {
|
||||
tabBar.translationY += dy
|
||||
tabBar.translationY = MathUtils.clamp(
|
||||
tabBar.translationY,
|
||||
0f,
|
||||
tabBar.height.toFloat()
|
||||
)
|
||||
updateViewsNearBottom()
|
||||
} else if (tabBar.translationY != 0f) {
|
||||
tabBar.translationY = 0f
|
||||
activityBinding!!.bottomView?.translationY = 0f
|
||||
}
|
||||
}
|
||||
if (!elevate && (
|
||||
dy == 0 ||
|
||||
(
|
||||
activityBinding!!.appBar.y <= -activityBinding!!.appBar.height.toFloat() ||
|
||||
dy == 0 && activityBinding!!.appBar.y == 0f
|
||||
)
|
||||
if (!isTablet) {
|
||||
activityBinding!!.appBar.y -= dy
|
||||
activityBinding!!.appBar.y = MathUtils.clamp(
|
||||
activityBinding!!.appBar.y,
|
||||
-activityBinding!!.appBar.height.toFloat(),
|
||||
0f
|
||||
)
|
||||
) {
|
||||
elevateFunc(true)
|
||||
activityBinding!!.bottomNav?.let { bottomNav ->
|
||||
if (bottomNav.isVisible && isInView) {
|
||||
if (preferences.hideBottomNavOnScroll().get()) {
|
||||
bottomNav.translationY += dy
|
||||
bottomNav.translationY = MathUtils.clamp(
|
||||
bottomNav.translationY,
|
||||
0f,
|
||||
bottomNav.height.toFloat()
|
||||
)
|
||||
updateViewsNearBottom()
|
||||
} else if (bottomNav.translationY != 0f) {
|
||||
bottomNav.translationY = 0f
|
||||
activityBinding!!.bottomView?.translationY = 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!elevate && (
|
||||
dy == 0 ||
|
||||
(
|
||||
activityBinding!!.appBar.y <= -activityBinding!!.appBar.height.toFloat() ||
|
||||
dy == 0 && activityBinding!!.appBar.y == 0f
|
||||
)
|
||||
)
|
||||
) {
|
||||
elevateFunc(true)
|
||||
}
|
||||
} else {
|
||||
val notAtTop = recycler.canScrollVertically(-1)
|
||||
if (notAtTop != elevate) elevateFunc(notAtTop)
|
||||
}
|
||||
lastY = activityBinding!!.appBar.y
|
||||
}
|
||||
@ -387,6 +417,9 @@ fun Controller.scrollViewWith(
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
|
||||
if (isTablet) {
|
||||
return
|
||||
}
|
||||
if (router?.backstack?.lastOrNull()
|
||||
?.controller == this@scrollViewWith && statusBarHeight > -1 &&
|
||||
activity != null && activityBinding!!.appBar.height > 0 &&
|
||||
@ -397,18 +430,20 @@ fun Controller.scrollViewWith(
|
||||
android.R.integer.config_shortAnimTime
|
||||
) ?: 0
|
||||
val closerToTop = abs(activityBinding!!.appBar.y) > halfWay
|
||||
val halfWayBottom = activityBinding!!.bottomNav.height.toFloat() / 2
|
||||
val closerToBottom = activityBinding!!.bottomNav.translationY > halfWayBottom
|
||||
val halfWayBottom = (activityBinding!!.bottomNav?.height?.toFloat() ?: 0f) / 2
|
||||
val closerToBottom = activityBinding!!.bottomNav?.translationY ?: 0f > halfWayBottom
|
||||
val atTop = !recycler.canScrollVertically(-1)
|
||||
val closerToEdge =
|
||||
if (activityBinding!!.bottomNav.isVisible &&
|
||||
if (activityBinding!!.bottomNav?.isVisible == true &&
|
||||
preferences.hideBottomNavOnScroll().get()
|
||||
) closerToBottom else closerToTop
|
||||
lastY =
|
||||
if (closerToEdge && !atTop) (-activityBinding!!.appBar.height.toFloat()) else 0f
|
||||
activityBinding!!.appBar.animate().y(lastY)
|
||||
.setDuration(shortAnimationDuration.toLong()).start()
|
||||
if (activityBinding!!.bottomNav.isVisible && isInView && preferences.hideBottomNavOnScroll().get()) {
|
||||
if (activityBinding!!.bottomNav?.isVisible == true &&
|
||||
isInView && preferences.hideBottomNavOnScroll().get()
|
||||
) {
|
||||
activityBinding!!.bottomNav?.let {
|
||||
val lastBottomY =
|
||||
if (closerToEdge && !atTop) it.height.toFloat() else 0f
|
||||
@ -447,8 +482,8 @@ fun Controller.requestPermissionsSafe(permissions: Array<String>, requestCode: I
|
||||
|
||||
fun Controller.withFadeTransaction(): RouterTransaction {
|
||||
return RouterTransaction.with(this)
|
||||
.pushChangeHandler(FadeChangeHandler())
|
||||
.popChangeHandler(FadeChangeHandler())
|
||||
.pushChangeHandler(OneWayFadeChangeHandler())
|
||||
.popChangeHandler(OneWayFadeChangeHandler())
|
||||
}
|
||||
|
||||
fun Controller.openInBrowser(url: String) {
|
||||
|
@ -31,10 +31,10 @@ import androidx.recyclerview.widget.LinearSmoothScroller
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.RecyclerView.SmoothScroller
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationItemView
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationMenuView
|
||||
import com.google.android.material.bottomnavigation.BottomNavigationView
|
||||
import com.google.android.material.button.MaterialButton
|
||||
import com.google.android.material.navigation.NavigationBarItemView
|
||||
import com.google.android.material.navigation.NavigationBarMenuView
|
||||
import com.google.android.material.navigation.NavigationBarView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.lang.tintText
|
||||
@ -259,9 +259,9 @@ fun TextView.setTextColorRes(@ColorRes id: Int) {
|
||||
}
|
||||
|
||||
@SuppressLint("RestrictedApi")
|
||||
fun BottomNavigationView.getItemView(@IdRes id: Int): BottomNavigationItemView? {
|
||||
fun NavigationBarView.getItemView(@IdRes id: Int): NavigationBarItemView? {
|
||||
val order = (menu as MenuBuilder).findItemIndex(id)
|
||||
return (getChildAt(0) as BottomNavigationMenuView).getChildAt(order) as? BottomNavigationItemView
|
||||
return (getChildAt(0) as NavigationBarMenuView).getChildAt(order) as? NavigationBarItemView
|
||||
}
|
||||
|
||||
fun RecyclerView.smoothScrollToTop() {
|
||||
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="180"
|
||||
android:endColor="@android:color/transparent"
|
||||
android:startColor="@color/md_black_1000_54"/>
|
||||
</shape>
|
220
app/src/main/res/layout-sw600dp/main_activity.xml
Normal file
220
app/src/main/res/layout-sw600dp/main_activity.xml
Normal file
@ -0,0 +1,220 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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/main_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.bluelinelabs.conductor.ChangeHandlerFrameLayout
|
||||
android:id="@+id/controller_container"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@id/side_nav"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="1.0">
|
||||
|
||||
</com.bluelinelabs.conductor.ChangeHandlerFrameLayout>
|
||||
|
||||
<com.google.android.material.navigationrail.NavigationRailView
|
||||
android:id="@+id/side_nav"
|
||||
style="@style/Widget.MaterialComponents.NavigationRailView.Colored"
|
||||
android:background="?android:colorBackground"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
app:itemIconTint="@color/bottom_nav_item_selector"
|
||||
app:itemRippleColor="@color/fullRippleColor"
|
||||
app:itemTextColor="@color/bottom_nav_item_selector"
|
||||
app:labelVisibilityMode="labeled"
|
||||
android:translationZ="-10dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/app_bar"
|
||||
app:menu="@menu/bottom_navigation" />
|
||||
|
||||
<View
|
||||
android:id="@+id/shadow_gap"
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="16dp"
|
||||
app:layout_constraintEnd_toEndOf="@id/side_nav"
|
||||
app:layout_constraintBottom_toTopOf="@id/side_nav" />
|
||||
|
||||
<View
|
||||
android:id="@+id/side_shadow"
|
||||
android:layout_width="6dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="bottom"
|
||||
android:alpha="0.13"
|
||||
android:translationZ="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="@id/side_nav"
|
||||
app:layout_constraintTop_toTopOf="@id/shadow_gap"
|
||||
android:background="@drawable/shape_gradient_start_shadow" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/tabs_frame_layout"
|
||||
android:clickable="true"
|
||||
android:visibility="gone"
|
||||
android:layout_width="0dp"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/app_bar"
|
||||
app:layout_constraintStart_toEndOf="@id/side_nav"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
tools:visibility="visible"
|
||||
tools:ignore="KeyboardInaccessibleWidget">
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/main_tabs"
|
||||
style="@style/Theme.Widget.Tabs.Highlight"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:tabGravity="fill"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/tab_shadow"
|
||||
android:layout_width="0dp"
|
||||
android:visibility="gone"
|
||||
android:layout_height="6dp"
|
||||
android:rotation="180"
|
||||
android:alpha="0.15"
|
||||
android:background="@drawable/shape_gradient_top_shadow"
|
||||
app:layout_constraintStart_toStartOf="@id/tabs_frame_layout"
|
||||
app:layout_constraintEnd_toEndOf="@id/tabs_frame_layout"
|
||||
app:layout_constraintTop_toBottomOf="@id/tabs_frame_layout"
|
||||
android:paddingBottom="10dp" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorSecondary"
|
||||
android:stateListAnimator="@null"
|
||||
android:theme="?attr/actionBarTheme"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<eu.kanade.tachiyomi.ui.base.CenteredToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
app:titleTextColor="?actionBarTintColor"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:collapseIcon="@drawable/ic_arrow_back_24dp"
|
||||
android:background="?attr/colorSecondary">
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/toolbar_title"
|
||||
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTint="?actionBarTintColor"
|
||||
android:ellipsize="end"
|
||||
android:layout_gravity="center"
|
||||
android:maxLines="1"
|
||||
android:textColor="?actionBarTintColor"
|
||||
android:textSize="20sp"
|
||||
tools:drawableEnd="@drawable/ic_arrow_drop_down_24dp"
|
||||
tools:drawableStart="@drawable/ic_blank_24dp"
|
||||
tools:text="Title Text" />
|
||||
</eu.kanade.tachiyomi.ui.base.CenteredToolbar>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/card_frame"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize" >
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_marginTop="4dp"
|
||||
app:cardBackgroundColor="?colorPrimaryVariant"
|
||||
android:layout_marginBottom="4dp"
|
||||
android:layout_marginStart="14dp"
|
||||
android:layout_marginEnd="14dp"
|
||||
app:cardCornerRadius="8dp"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<eu.kanade.tachiyomi.ui.base.FloatingToolbar
|
||||
android:id="@+id/card_toolbar"
|
||||
tools:title="Search Library..."
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
app:contentInsetEndWithActions="0dp"
|
||||
app:contentInsetStart="0dp"
|
||||
app:contentInsetEnd="0dp"
|
||||
android:background="@drawable/rect_ripple"
|
||||
app:navigationIconTint="@color/text_color_secondary"
|
||||
app:navigationIcon="@drawable/ic_search_24dp"
|
||||
app:titleTextAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:subtitleTextAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
app:collapseIcon="@drawable/ic_arrow_back_24dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/card_incog_image"
|
||||
app:tint="?actionBarTintColor"
|
||||
android:layout_gravity="center|start"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:layout_marginEnd="6dp"
|
||||
android:layout_marginStart="0dp"
|
||||
android:contentDescription="@string/incognito_mode"
|
||||
android:src="@drawable/ic_incognito_circle_24dp"/>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="start|center"
|
||||
android:orientation="vertical">
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/card_title"
|
||||
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableTint="?actionBarTintColor"
|
||||
android:ellipsize="end"
|
||||
android:layout_gravity="center"
|
||||
android:maxLines="1"
|
||||
android:textColor="?actionBarTintColor"
|
||||
android:textSize="20sp"
|
||||
tools:drawableEnd="@drawable/ic_arrow_drop_down_24dp"
|
||||
tools:drawableStart="@drawable/ic_blank_24dp"
|
||||
tools:text="Title Text" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:id="@+id/card_subtitle"
|
||||
style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:layout_gravity="start|center"
|
||||
android:maxLines="1"
|
||||
android:textColor="?actionBarTintColor"
|
||||
android:textSize="12sp"
|
||||
tools:text="Title Text" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</eu.kanade.tachiyomi.ui.base.FloatingToolbar>
|
||||
</androidx.cardview.widget.CardView>
|
||||
</FrameLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in New Issue
Block a user