mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Add back pressed animation + update controller push/pop animation
Likely am gonna revert for the stable just to save myself the headache Limiting the new animations to Android 10+, new animations will still play on 10+ devices, but wont keep the view on low ram devices
This commit is contained in:
parent
a6c49f0970
commit
59e11ff486
12 changed files with 224 additions and 70 deletions
|
@ -269,9 +269,9 @@ dependencies {
|
|||
implementation("com.getkeepsafe.taptargetview:taptargetview:1.13.3")
|
||||
|
||||
// Conductor
|
||||
val conductorVersion = "3.0.0"
|
||||
val conductorVersion = "4.0.0-preview-3"
|
||||
implementation("com.bluelinelabs:conductor:$conductorVersion")
|
||||
implementation("com.github.tachiyomiorg:conductor-support-preference:$conductorVersion")
|
||||
implementation("com.github.tachiyomiorg:conductor-support-preference:3.0.0")
|
||||
|
||||
// Shizuku
|
||||
val shizukuVersion = "12.1.0"
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.view.Menu
|
|||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.activity.BackEventCompat
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.forEach
|
||||
import androidx.core.view.isVisible
|
||||
|
@ -18,6 +17,7 @@ import com.bluelinelabs.conductor.Controller
|
|||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.util.view.BackHandlerControllerInterface
|
||||
import eu.kanade.tachiyomi.util.view.activityBinding
|
||||
import eu.kanade.tachiyomi.util.view.isControllerVisible
|
||||
import eu.kanade.tachiyomi.util.view.removeQueryListener
|
||||
|
@ -27,7 +27,7 @@ import kotlinx.coroutines.cancel
|
|||
import timber.log.Timber
|
||||
|
||||
abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
||||
Controller(bundle) {
|
||||
Controller(bundle), BackHandlerControllerInterface {
|
||||
|
||||
lateinit var binding: VB
|
||||
lateinit var viewScope: CoroutineScope
|
||||
|
@ -72,12 +72,14 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||
open fun onViewCreated(view: View) { }
|
||||
|
||||
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||
if (type.isEnter) {
|
||||
if (type.isEnter && isControllerVisible) {
|
||||
setTitle()
|
||||
} else if (type.isEnter) {
|
||||
view?.alpha = 0f
|
||||
} else {
|
||||
removeQueryListener()
|
||||
}
|
||||
setHasOptionsMenu(type.isEnter)
|
||||
setHasOptionsMenu(type.isEnter && isControllerVisible)
|
||||
super.onChangeStarted(handler, type)
|
||||
}
|
||||
|
||||
|
@ -95,12 +97,6 @@ abstract class BaseController<VB : ViewBinding>(bundle: Bundle? = null) :
|
|||
|
||||
open fun canStillGoBack(): Boolean { return false }
|
||||
|
||||
open fun handleOnBackStarted(backEvent: BackEventCompat) {}
|
||||
|
||||
open fun handleOnBackProgressed(backEvent: BackEventCompat) {}
|
||||
|
||||
open fun handleOnBackCancelled() {}
|
||||
|
||||
open val mainRecycler: RecyclerView?
|
||||
get() = null
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
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.AnimatorChangeHandler
|
||||
|
||||
class CrossFadeChangeHandler : AnimatorChangeHandler {
|
||||
constructor() : super()
|
||||
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 animatorSet = AnimatorSet()
|
||||
if (to != null) {
|
||||
val start = if (toAddedToContainer) 0F else to.alpha
|
||||
animatorSet.play(ObjectAnimator.ofFloat(to, View.ALPHA, start, 1f))
|
||||
}
|
||||
if (from != null) {
|
||||
animatorSet.play(ObjectAnimator.ofFloat(from, View.ALPHA, 0f))
|
||||
}
|
||||
if (isPush) {
|
||||
if (from != null) {
|
||||
animatorSet.play(ObjectAnimator.ofFloat(from, View.TRANSLATION_X, -from.width.toFloat() * 0.2f))
|
||||
}
|
||||
if (to != null) {
|
||||
animatorSet.play(ObjectAnimator.ofFloat(to, View.TRANSLATION_X, to.width.toFloat() * 0.2f, 0f))
|
||||
}
|
||||
} else {
|
||||
if (from != null) {
|
||||
animatorSet.play(ObjectAnimator.ofFloat(from, View.TRANSLATION_X, from.width.toFloat() * 0.2f))
|
||||
}
|
||||
if (to != null) {
|
||||
// Allow this to have a nice transition when coming off an aborted push animation
|
||||
val fromLeft = from?.translationX ?: 0F
|
||||
animatorSet.play(ObjectAnimator.ofFloat(to, View.TRANSLATION_X, fromLeft - to.width * 0.2f, 0f))
|
||||
}
|
||||
}
|
||||
return animatorSet
|
||||
}
|
||||
|
||||
override fun resetFromView(from: View) {
|
||||
from.translationX = 0f
|
||||
}
|
||||
|
||||
override fun copy(): ControllerChangeHandler =
|
||||
CrossFadeChangeHandler(animationDuration, removesFromViewOnPush)
|
||||
}
|
|
@ -6,12 +6,13 @@ import android.animation.ObjectAnimator
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.bluelinelabs.conductor.ControllerChangeHandler
|
||||
import com.bluelinelabs.conductor.changehandler.AnimatorChangeHandler
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
|
||||
/**
|
||||
* A variation of [FadeChangeHandler] that only fades in.
|
||||
*/
|
||||
class OneWayFadeChangeHandler : FadeChangeHandler {
|
||||
class OneWayFadeChangeHandler : AnimatorChangeHandler {
|
||||
constructor()
|
||||
constructor(removesFromViewOnPush: Boolean) : super(removesFromViewOnPush)
|
||||
constructor(duration: Long) : super(duration)
|
||||
|
@ -20,7 +21,6 @@ class OneWayFadeChangeHandler : FadeChangeHandler {
|
|||
removesFromViewOnPush,
|
||||
)
|
||||
|
||||
var fadeOut = true
|
||||
override fun getAnimator(
|
||||
container: ViewGroup,
|
||||
from: View?,
|
||||
|
@ -34,17 +34,17 @@ class OneWayFadeChangeHandler : FadeChangeHandler {
|
|||
animator.play(ObjectAnimator.ofFloat(to, View.ALPHA, start, 1f))
|
||||
}
|
||||
|
||||
if (from != null && (!isPush || removesFromViewOnPush())) {
|
||||
if (fadeOut) {
|
||||
animator.play(ObjectAnimator.ofFloat(from, View.ALPHA, 0f))
|
||||
} else {
|
||||
container.removeView(from)
|
||||
}
|
||||
if (from != null && (!isPush || removesFromViewOnPush)) {
|
||||
container.removeView(from)
|
||||
}
|
||||
return animator
|
||||
}
|
||||
|
||||
override fun resetFromView(from: View) {
|
||||
from.alpha = 1f
|
||||
}
|
||||
|
||||
override fun copy(): ControllerChangeHandler {
|
||||
return OneWayFadeChangeHandler(animationDuration, removesFromViewOnPush())
|
||||
return OneWayFadeChangeHandler(animationDuration, removesFromViewOnPush)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import android.view.Window
|
|||
import android.view.WindowManager
|
||||
import androidx.activity.BackEventCompat
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.activity.addCallback
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.appcompat.view.ActionMode
|
||||
|
@ -115,6 +114,7 @@ import eu.kanade.tachiyomi.util.system.materialAlertDialog
|
|||
import eu.kanade.tachiyomi.util.system.prepareSideNavContext
|
||||
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
|
||||
import eu.kanade.tachiyomi.util.system.toast
|
||||
import eu.kanade.tachiyomi.util.view.BackHandlerControllerInterface
|
||||
import eu.kanade.tachiyomi.util.view.backgroundColor
|
||||
import eu.kanade.tachiyomi.util.view.blurBehindWindow
|
||||
import eu.kanade.tachiyomi.util.view.canStillGoBack
|
||||
|
@ -212,7 +212,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
get() = max(binding.toolbar.height, binding.cardFrame.height, binding.appBar.attrToolbarHeight)
|
||||
|
||||
private var actionMode: ActionMode? = null
|
||||
var backPressedCallback: OnBackPressedCallback? = null
|
||||
private var backPressedCallback: OnBackPressedCallback? = null
|
||||
private val backCallback = {
|
||||
pressingBack()
|
||||
reEnableBackPressedCallBack()
|
||||
|
@ -253,23 +253,41 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
|
||||
super.onCreate(savedInstanceState)
|
||||
backPressedCallback = object : OnBackPressedCallback(enabled = true) {
|
||||
var controllerHandlesBackPress = false
|
||||
override fun handleOnBackPressed() {
|
||||
backCallback()
|
||||
}
|
||||
|
||||
override fun handleOnBackStarted(backEvent: BackEventCompat) {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BaseController<*>
|
||||
controller?.handleOnBackStarted(backEvent)
|
||||
controllerHandlesBackPress = false
|
||||
if (!(
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
|
||||
ViewCompat.getRootWindowInsets(window.decorView)
|
||||
?.isVisible(WindowInsetsCompat.Type.ime()) == true
|
||||
) &&
|
||||
actionMode == null &&
|
||||
!(binding.searchToolbar.hasExpandedActionView() && binding.cardFrame.isVisible)
|
||||
) {
|
||||
controllerHandlesBackPress = true
|
||||
}
|
||||
if (controllerHandlesBackPress) {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BackHandlerControllerInterface
|
||||
controller?.handleOnBackStarted(backEvent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BaseController<*>
|
||||
controller?.handleOnBackProgressed(backEvent)
|
||||
if (controllerHandlesBackPress) {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BackHandlerControllerInterface
|
||||
controller?.handleOnBackProgressed(backEvent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackCancelled() {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BaseController<*>
|
||||
controller?.handleOnBackCancelled()
|
||||
if (controllerHandlesBackPress) {
|
||||
val controller = router.backstack.lastOrNull()?.controller as? BackHandlerControllerInterface
|
||||
controller?.handleOnBackCancelled()
|
||||
}
|
||||
}
|
||||
}
|
||||
onBackPressedDispatcher.addCallback(backPressedCallback!!)
|
||||
|
@ -501,6 +519,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
container: ViewGroup,
|
||||
handler: ControllerChangeHandler,
|
||||
) {
|
||||
to?.view?.alpha = 1f
|
||||
syncActivityViewWithController(to, from, isPush)
|
||||
binding.appBar.isVisible = true
|
||||
binding.appBar.alpha = 1f
|
||||
|
@ -519,6 +538,9 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
) {
|
||||
nav.translationY = 0f
|
||||
showDLQueueTutorial()
|
||||
if (!(from is DialogController || to is DialogController) && from != null) {
|
||||
from.view?.alpha = 0f
|
||||
}
|
||||
if (router.backstackSize == 1) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && !isPush) {
|
||||
window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)
|
||||
|
@ -705,8 +727,8 @@ open class MainActivity : BaseActivity<MainActivityBinding>() {
|
|||
if (insets == null) return
|
||||
window.navigationBarColor = when {
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1 -> {
|
||||
// basically if in landscape on a phone
|
||||
// For lollipop, draw opaque nav bar
|
||||
// basically if in landscape on a phone, solid black bar
|
||||
// otherwise translucent dark theme or black if light theme
|
||||
when {
|
||||
insets.hasSideNavBar() -> Color.BLACK
|
||||
isInNightMode() -> ColorUtils.setAlphaComponent(
|
||||
|
|
|
@ -661,10 +661,12 @@ class MangaDetailsController :
|
|||
super.onChangeStarted(handler, type)
|
||||
isPushing = true
|
||||
if (type.isEnter) {
|
||||
activityBinding?.appBar?.y = 0f
|
||||
activityBinding?.appBar?.updateAppBarAfterY(binding.recycler)
|
||||
updateToolbarTitleAlpha(0f)
|
||||
setStatusBarAndToolbar()
|
||||
if (isControllerVisible) {
|
||||
activityBinding?.appBar?.y = 0f
|
||||
activityBinding?.appBar?.updateAppBarAfterY(binding.recycler)
|
||||
updateToolbarTitleAlpha(0f)
|
||||
setStatusBarAndToolbar()
|
||||
}
|
||||
} else {
|
||||
if (router.backstack.lastOrNull()?.controller is DialogController) {
|
||||
return
|
||||
|
|
|
@ -495,12 +495,16 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
||||
if (showingDownloads) {
|
||||
binding.downloadBottomSheet.dlBottomSheet.sheetBehavior?.updateBackProgress(backEvent)
|
||||
} else {
|
||||
super.handleOnBackProgressed(backEvent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackCancelled() {
|
||||
if (showingDownloads) {
|
||||
binding.downloadBottomSheet.dlBottomSheet.sheetBehavior?.cancelBackProgress()
|
||||
} else {
|
||||
super.handleOnBackCancelled()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -889,30 +893,33 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
if (type.isEnter) {
|
||||
if (type == ControllerChangeType.POP_ENTER) presenter.onCreate()
|
||||
binding.downloadBottomSheet.dlBottomSheet.dismiss()
|
||||
activityBinding?.mainTabs?.let { tabs ->
|
||||
tabs.removeAllTabs()
|
||||
tabs.clearOnTabSelectedListeners()
|
||||
val selectedTab = presenter.viewType
|
||||
RecentsViewType.entries.forEach { viewType ->
|
||||
tabs.addTab(
|
||||
tabs.newTab().setText(viewType.stringRes).also { tab ->
|
||||
tab.view.compatToolTipText = null
|
||||
if (isControllerVisible) {
|
||||
activityBinding?.mainTabs?.let { tabs ->
|
||||
tabs.removeAllTabs()
|
||||
tabs.clearOnTabSelectedListeners()
|
||||
val selectedTab = presenter.viewType
|
||||
RecentsViewType.entries.forEach { viewType ->
|
||||
tabs.addTab(
|
||||
tabs.newTab().setText(viewType.stringRes).also { tab ->
|
||||
tab.view.compatToolTipText = null
|
||||
},
|
||||
viewType == selectedTab,
|
||||
)
|
||||
}
|
||||
tabs.addOnTabSelectedListener(
|
||||
object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||
setViewType(RecentsViewType.valueOf(tab?.position))
|
||||
}
|
||||
|
||||
override fun onTabUnselected(tab: TabLayout.Tab?) {}
|
||||
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||
binding.recycler.smoothScrollToTop()
|
||||
}
|
||||
},
|
||||
viewType == selectedTab,
|
||||
)
|
||||
(activity as? MainActivity)?.showTabBar(true)
|
||||
}
|
||||
tabs.addOnTabSelectedListener(
|
||||
object : TabLayout.OnTabSelectedListener {
|
||||
override fun onTabSelected(tab: TabLayout.Tab?) {
|
||||
setViewType(RecentsViewType.valueOf(tab?.position))
|
||||
}
|
||||
override fun onTabUnselected(tab: TabLayout.Tab?) {}
|
||||
override fun onTabReselected(tab: TabLayout.Tab?) {
|
||||
binding.recycler.smoothScrollToTop()
|
||||
}
|
||||
},
|
||||
)
|
||||
(activity as? MainActivity)?.showTabBar(true)
|
||||
}
|
||||
} else {
|
||||
val lastController = router.backstack.lastOrNull()?.controller
|
||||
|
@ -929,7 +936,7 @@ class RecentsController(bundle: Bundle? = null) :
|
|||
if (type == ControllerChangeType.POP_ENTER) {
|
||||
setBottomPadding()
|
||||
}
|
||||
if (type.isEnter) {
|
||||
if (type.isEnter && isControllerVisible) {
|
||||
updateTitleAndMenu()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,10 @@ import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
|||
import eu.kanade.tachiyomi.ui.main.FloatingSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
import eu.kanade.tachiyomi.util.system.getResourceColor
|
||||
import eu.kanade.tachiyomi.util.view.BackHandlerControllerInterface
|
||||
import eu.kanade.tachiyomi.util.view.activityBinding
|
||||
import eu.kanade.tachiyomi.util.view.backgroundColor
|
||||
import eu.kanade.tachiyomi.util.view.isControllerVisible
|
||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||
import eu.kanade.tachiyomi.widget.LinearLayoutManagerAccurateOffset
|
||||
import kotlinx.coroutines.MainScope
|
||||
|
@ -34,7 +37,7 @@ import uy.kohesive.injekt.Injekt
|
|||
import uy.kohesive.injekt.api.get
|
||||
import java.util.Locale
|
||||
|
||||
abstract class SettingsController : PreferenceController() {
|
||||
abstract class SettingsController : PreferenceController(), BackHandlerControllerInterface {
|
||||
|
||||
var preferenceKey: String? = null
|
||||
val preferences: PreferencesHelper = Injekt.get()
|
||||
|
@ -47,6 +50,7 @@ abstract class SettingsController : PreferenceController() {
|
|||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup, savedInstanceState: Bundle?): View {
|
||||
val view = super.onCreateView(inflater, container, savedInstanceState)
|
||||
view.backgroundColor = view.context.getResourceColor(R.attr.background)
|
||||
scrollViewWith(listView, padBottom = true)
|
||||
return view
|
||||
}
|
||||
|
@ -123,10 +127,12 @@ abstract class SettingsController : PreferenceController() {
|
|||
}
|
||||
|
||||
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||
if (type.isEnter) {
|
||||
if (type.isEnter && isControllerVisible) {
|
||||
setTitle()
|
||||
} else if (type.isEnter) {
|
||||
view?.alpha = 0f
|
||||
}
|
||||
setHasOptionsMenu(type.isEnter)
|
||||
setHasOptionsMenu(type.isEnter && isControllerVisible)
|
||||
super.onChangeStarted(handler, type)
|
||||
}
|
||||
|
||||
|
|
|
@ -358,7 +358,7 @@ class BrowseController :
|
|||
val controller = ExtensionFilterController()
|
||||
router.pushController(
|
||||
RouterTransaction.with(controller)
|
||||
.popChangeHandler(SettingsSourcesFadeChangeHandler())
|
||||
.popChangeHandler(FadeChangeHandler())
|
||||
.pushChangeHandler(FadeChangeHandler()),
|
||||
)
|
||||
}
|
||||
|
@ -494,12 +494,16 @@ class BrowseController :
|
|||
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
||||
if (showingExtensions && !binding.bottomSheet.root.canStillGoBack()) {
|
||||
binding.bottomSheet.root.sheetBehavior?.updateBackProgress(backEvent)
|
||||
} else {
|
||||
super.handleOnBackProgressed(backEvent)
|
||||
}
|
||||
}
|
||||
|
||||
override fun handleOnBackCancelled() {
|
||||
if (showingExtensions && !binding.bottomSheet.root.canStillGoBack()) {
|
||||
binding.bottomSheet.root.sheetBehavior?.cancelBackProgress()
|
||||
} else {
|
||||
super.handleOnBackCancelled()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -531,7 +535,7 @@ class BrowseController :
|
|||
binding.bottomSheet.root.updateExtTitle()
|
||||
binding.bottomSheet.root.presenter.refreshExtensions()
|
||||
presenter.updateSources()
|
||||
if (type.isEnter) {
|
||||
if (type.isEnter && isControllerVisible) {
|
||||
activityBinding?.appBar?.doOnNextLayout {
|
||||
activityBinding?.appBar?.y = 0f
|
||||
activityBinding?.appBar?.updateAppBarAfterY(binding.sourceRecycler)
|
||||
|
@ -696,7 +700,7 @@ class BrowseController :
|
|||
val controller = SettingsSourcesController()
|
||||
router.pushController(
|
||||
RouterTransaction.with(controller)
|
||||
.popChangeHandler(SettingsSourcesFadeChangeHandler())
|
||||
.popChangeHandler(FadeChangeHandler())
|
||||
.pushChangeHandler(FadeChangeHandler()),
|
||||
)
|
||||
}
|
||||
|
@ -733,8 +737,6 @@ class BrowseController :
|
|||
}
|
||||
}
|
||||
|
||||
class SettingsSourcesFadeChangeHandler : FadeChangeHandler()
|
||||
|
||||
@Parcelize
|
||||
data class SmartSearchConfig(val origTitle: String, val origMangaId: Long) : Parcelable
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import eu.kanade.tachiyomi.ui.source.browse.BrowseSourceController
|
|||
import eu.kanade.tachiyomi.util.addOrRemoveToFavorites
|
||||
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
|
||||
import eu.kanade.tachiyomi.util.view.activityBinding
|
||||
import eu.kanade.tachiyomi.util.view.isControllerVisible
|
||||
import eu.kanade.tachiyomi.util.view.scrollViewWith
|
||||
import eu.kanade.tachiyomi.util.view.setOnQueryTextChangeListener
|
||||
import eu.kanade.tachiyomi.util.view.snack
|
||||
|
@ -169,7 +170,7 @@ open class GlobalSearchController(
|
|||
|
||||
override fun onChangeStarted(handler: ControllerChangeHandler, type: ControllerChangeType) {
|
||||
super.onChangeStarted(handler, type)
|
||||
if (type.isEnter) {
|
||||
if (type.isEnter && isControllerVisible) {
|
||||
val searchView = activityBinding?.searchToolbar?.searchView ?: return
|
||||
val searchItem = activityBinding?.searchToolbar?.searchItem ?: return
|
||||
searchItem.expandActionView()
|
||||
|
|
|
@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.util.view
|
|||
import android.Manifest
|
||||
import android.animation.Animator
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.ActivityManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
|
@ -18,10 +19,13 @@ import android.view.ViewGroup.LayoutParams.MATCH_PARENT
|
|||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import androidx.activity.BackEventCompat
|
||||
import androidx.annotation.CallSuper
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.cardview.widget.CardView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.getSystemService
|
||||
import androidx.core.graphics.ColorUtils
|
||||
import androidx.core.math.MathUtils
|
||||
import androidx.core.net.toUri
|
||||
|
@ -45,6 +49,7 @@ import com.bluelinelabs.conductor.ControllerChangeHandler
|
|||
import com.bluelinelabs.conductor.ControllerChangeType
|
||||
import com.bluelinelabs.conductor.Router
|
||||
import com.bluelinelabs.conductor.RouterTransaction
|
||||
import com.bluelinelabs.conductor.changehandler.FadeChangeHandler
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.backup.BackupCreatorJob
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
|
@ -52,6 +57,7 @@ import eu.kanade.tachiyomi.databinding.MainActivityBinding
|
|||
import eu.kanade.tachiyomi.ui.base.SmallToolbarInterface
|
||||
import eu.kanade.tachiyomi.ui.base.controller.BaseController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||
import eu.kanade.tachiyomi.ui.base.controller.CrossFadeChangeHandler
|
||||
import eu.kanade.tachiyomi.ui.base.controller.OneWayFadeChangeHandler
|
||||
import eu.kanade.tachiyomi.ui.main.FloatingSearchInterface
|
||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
||||
|
@ -70,6 +76,7 @@ import eu.kanade.tachiyomi.widget.StatefulNestedScrollView
|
|||
import uy.kohesive.injekt.injectLazy
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.max
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
|
@ -664,7 +671,9 @@ fun Controller.moveRecyclerViewUp(allTheWayUp: Boolean = false, scrollUpAnyway:
|
|||
val recycler = mainRecyclerView ?: return
|
||||
val activityBinding = activityBinding ?: return
|
||||
val appBarOffset = activityBinding.appBar.toolbarDistanceToTop
|
||||
if (allTheWayUp && recycler.computeVerticalScrollOffset() - recycler.paddingTop <= fullAppBarHeight ?: activityBinding.appBar.preLayoutHeight) {
|
||||
if (allTheWayUp && recycler.computeVerticalScrollOffset() - recycler.paddingTop <=
|
||||
(fullAppBarHeight ?: activityBinding.appBar.preLayoutHeight)
|
||||
) {
|
||||
(recycler.layoutManager as? LinearLayoutManager)?.scrollToPosition(0)
|
||||
(recycler.layoutManager as? StaggeredGridLayoutManager)?.scrollToPosition(0)
|
||||
recycler.post {
|
||||
|
@ -782,14 +791,27 @@ fun Controller.requestFilePermissionsSafe(
|
|||
}
|
||||
|
||||
fun Controller.withFadeTransaction(): RouterTransaction {
|
||||
val isLowRam by lazy { activity?.getSystemService<ActivityManager>()?.isLowRamDevice == true }
|
||||
return RouterTransaction.with(this)
|
||||
.pushChangeHandler(OneWayFadeChangeHandler())
|
||||
.popChangeHandler(OneWayFadeChangeHandler())
|
||||
.pushChangeHandler(
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
FadeChangeHandler()
|
||||
} else {
|
||||
CrossFadeChangeHandler(duration = 250, removesFromViewOnPush = isLowRam)
|
||||
},
|
||||
)
|
||||
.popChangeHandler(
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
|
||||
FadeChangeHandler()
|
||||
} else {
|
||||
CrossFadeChangeHandler(duration = 150, removesFromViewOnPush = isLowRam)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fun Controller.withFadeInTransaction(): RouterTransaction {
|
||||
return RouterTransaction.with(this)
|
||||
.pushChangeHandler(OneWayFadeChangeHandler().apply { fadeOut = false })
|
||||
.pushChangeHandler(FadeChangeHandler())
|
||||
.popChangeHandler(OneWayFadeChangeHandler())
|
||||
}
|
||||
|
||||
|
@ -830,3 +852,37 @@ fun Router.canStillGoBack(): Boolean {
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
interface BackHandlerControllerInterface {
|
||||
fun handleOnBackStarted(backEvent: BackEventCompat) {
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
||||
if (this !is Controller) return
|
||||
if (router.backstackSize > 1) {
|
||||
val progress = ((backEvent.progress.takeIf { it > 0.001f } ?: 0f) * 0.5f).pow(0.6f)
|
||||
view?.let { view ->
|
||||
view.alpha = 1f - progress
|
||||
view.x = progress * view.width * 0.15f
|
||||
router.backstack[router.backstackSize - 2].controller.view?.let { view2 ->
|
||||
view2.alpha = progress
|
||||
view2.x = view.x - view.width * 0.2f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
fun handleOnBackCancelled() {
|
||||
if (this !is Controller) return
|
||||
view?.alpha = 1f
|
||||
view?.x = 0f
|
||||
if (router.backstackSize > 1) {
|
||||
router.backstack[router.backstackSize - 2].controller.view?.let { view ->
|
||||
view.alpha = 0f
|
||||
view.x = 0f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:background="?background"
|
||||
android:layout_width="match_parent"
|
||||
android:id="@+id/source_layout"
|
||||
android:layout_height="match_parent">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue