mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-11-14 04:45:07 +01:00
Animating swipe for category hopper
So its more clear that it's swipeable
This commit is contained in:
parent
28f5a6986f
commit
46374e0582
@ -16,6 +16,7 @@ import android.view.LayoutInflater
|
|||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.ViewPropertyAnimator
|
import android.view.ViewPropertyAnimator
|
||||||
@ -194,6 +195,7 @@ class LibraryController(
|
|||||||
|
|
||||||
private var filterTooltip: ViewTooltip? = null
|
private var filterTooltip: ViewTooltip? = null
|
||||||
private var isAnimatingHopper: Boolean? = null
|
private var isAnimatingHopper: Boolean? = null
|
||||||
|
private var animatorSet: AnimatorSet? = null
|
||||||
var hasMovedHopper = preferences.shownHopperSwipeTutorial().get()
|
var hasMovedHopper = preferences.shownHopperSwipeTutorial().get()
|
||||||
private var shouldScrollToTop = false
|
private var shouldScrollToTop = false
|
||||||
private val showCategoryInTitle
|
private val showCategoryInTitle
|
||||||
@ -542,7 +544,7 @@ class LibraryController(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("RtlHardcoded")
|
@SuppressLint("RtlHardcoded", "ClickableViewAccessibility")
|
||||||
private fun setUpHopper() {
|
private fun setUpHopper() {
|
||||||
category_hopper_frame.gone()
|
category_hopper_frame.gone()
|
||||||
down_category.setOnClickListener {
|
down_category.setOnClickListener {
|
||||||
@ -598,10 +600,21 @@ class LibraryController(
|
|||||||
val gestureDetector = GestureDetectorCompat(activity, LibraryGestureDetector(this))
|
val gestureDetector = GestureDetectorCompat(activity, LibraryGestureDetector(this))
|
||||||
listOf(category_hopper_layout, up_category, down_category, category_button).forEach {
|
listOf(category_hopper_layout, up_category, down_category, category_button).forEach {
|
||||||
it.setOnTouchListener { _, event ->
|
it.setOnTouchListener { _, event ->
|
||||||
|
if (event?.action == MotionEvent.ACTION_DOWN) {
|
||||||
|
animatorSet?.end()
|
||||||
|
}
|
||||||
|
if (event?.action == MotionEvent.ACTION_UP) {
|
||||||
|
val result = gestureDetector.onTouchEvent(event)
|
||||||
|
if (!result) {
|
||||||
|
category_hopper_frame.animate().setDuration(150L).translationX(0f).start()
|
||||||
|
}
|
||||||
|
result
|
||||||
|
} else {
|
||||||
gestureDetector.onTouchEvent(event)
|
gestureDetector.onTouchEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun updateHopperY() {
|
fun updateHopperY() {
|
||||||
val view = view ?: return
|
val view = view ?: return
|
||||||
@ -884,6 +897,7 @@ class LibraryController(
|
|||||||
isAnimatingHopper = true
|
isAnimatingHopper = true
|
||||||
val slide = 25f.dpToPx
|
val slide = 25f.dpToPx
|
||||||
val animatorSet = AnimatorSet()
|
val animatorSet = AnimatorSet()
|
||||||
|
this.animatorSet = animatorSet
|
||||||
val animations = listOf(
|
val animations = listOf(
|
||||||
slideAnimation(0f, slide, 200),
|
slideAnimation(0f, slide, 200),
|
||||||
slideAnimation(slide, -slide),
|
slideAnimation(slide, -slide),
|
||||||
@ -895,7 +909,9 @@ class LibraryController(
|
|||||||
animatorSet.startDelay = 1250
|
animatorSet.startDelay = 1250
|
||||||
animatorSet.addListener(
|
animatorSet.addListener(
|
||||||
EndAnimatorListener {
|
EndAnimatorListener {
|
||||||
|
category_hopper_frame.translationX = 0f
|
||||||
isAnimatingHopper = false
|
isAnimatingHopper = false
|
||||||
|
this.animatorSet = null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
animatorSet.start()
|
animatorSet.start()
|
||||||
|
@ -4,12 +4,13 @@ import android.view.GestureDetector
|
|||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
import androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||||
import eu.kanade.tachiyomi.ui.main.MainActivity
|
|
||||||
import eu.kanade.tachiyomi.util.view.hide
|
import eu.kanade.tachiyomi.util.view.hide
|
||||||
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
import eu.kanade.tachiyomi.util.view.updateLayoutParams
|
||||||
import kotlinx.android.synthetic.main.filter_bottom_sheet.*
|
import kotlinx.android.synthetic.main.filter_bottom_sheet.*
|
||||||
import kotlinx.android.synthetic.main.library_list_controller.*
|
import kotlinx.android.synthetic.main.library_list_controller.*
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.sign
|
||||||
|
|
||||||
class LibraryGestureDetector(private val controller: LibraryController) : GestureDetector
|
class LibraryGestureDetector(private val controller: LibraryController) : GestureDetector
|
||||||
.SimpleOnGestureListener() {
|
.SimpleOnGestureListener() {
|
||||||
@ -17,6 +18,22 @@ class LibraryGestureDetector(private val controller: LibraryController) : Gestur
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onScroll(
|
||||||
|
e1: MotionEvent?,
|
||||||
|
e2: MotionEvent?,
|
||||||
|
distanceX: Float,
|
||||||
|
distanceY: Float
|
||||||
|
): Boolean {
|
||||||
|
val distance = ((e1?.rawX ?: 0f) - (e2?.rawX ?: 0f)) / 50
|
||||||
|
val poa = 1.7f
|
||||||
|
controller.category_hopper_frame.translationX = abs(distance).pow(poa) * -sign(distance)
|
||||||
|
return super.onScroll(e1, e2, distanceX, distanceY)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSingleTapUp(e: MotionEvent?): Boolean {
|
||||||
|
return super.onSingleTapUp(e)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onFling(
|
override fun onFling(
|
||||||
e1: MotionEvent,
|
e1: MotionEvent,
|
||||||
e2: MotionEvent,
|
e2: MotionEvent,
|
||||||
@ -26,21 +43,30 @@ class LibraryGestureDetector(private val controller: LibraryController) : Gestur
|
|||||||
var result = false
|
var result = false
|
||||||
val diffY = e2.y - e1.y
|
val diffY = e2.y - e1.y
|
||||||
val diffX = e2.x - e1.x
|
val diffX = e2.x - e1.x
|
||||||
|
val animator = controller.category_hopper_frame.animate().setDuration(150L)
|
||||||
|
animator.translationX(0f)
|
||||||
|
animator.withEndAction {
|
||||||
|
controller.category_hopper_frame.translationX = 0f
|
||||||
|
}
|
||||||
if (abs(diffX) <= abs(diffY) &&
|
if (abs(diffX) <= abs(diffY) &&
|
||||||
abs(diffY) > MainActivity.SWIPE_THRESHOLD &&
|
abs(diffY) > SWIPE_THRESHOLD &&
|
||||||
abs(velocityY) > MainActivity.SWIPE_VELOCITY_THRESHOLD
|
abs(velocityY) > SWIPE_VELOCITY_THRESHOLD
|
||||||
) {
|
) {
|
||||||
if (diffY <= 0) {
|
if (diffY <= 0) {
|
||||||
controller.showSheet()
|
controller.showSheet()
|
||||||
} else {
|
} else {
|
||||||
controller.filter_bottom_sheet.sheetBehavior?.hide()
|
controller.filter_bottom_sheet.sheetBehavior?.hide()
|
||||||
}
|
}
|
||||||
result = true
|
|
||||||
} else if (abs(diffX) >= abs(diffY) &&
|
} else if (abs(diffX) >= abs(diffY) &&
|
||||||
abs(diffX) > MainActivity.SWIPE_THRESHOLD * 3 &&
|
abs(diffX) > SWIPE_THRESHOLD * 5 &&
|
||||||
abs(velocityX) > MainActivity.SWIPE_VELOCITY_THRESHOLD
|
abs(velocityX) > SWIPE_VELOCITY_THRESHOLD
|
||||||
) {
|
) {
|
||||||
|
val hopperGravity = (controller.category_hopper_frame.layoutParams as CoordinatorLayout.LayoutParams).gravity
|
||||||
if (diffX <= 0) {
|
if (diffX <= 0) {
|
||||||
|
animator.translationX(
|
||||||
|
if (hopperGravity == Gravity.TOP or Gravity.LEFT) 0f
|
||||||
|
else (-(controller.view!!.width - controller.category_hopper_frame.width) / 2).toFloat()
|
||||||
|
).withEndAction {
|
||||||
controller.category_hopper_frame.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
controller.category_hopper_frame.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||||
gravity =
|
gravity =
|
||||||
Gravity.TOP or (
|
Gravity.TOP or (
|
||||||
@ -53,7 +79,13 @@ class LibraryGestureDetector(private val controller: LibraryController) : Gestur
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
savePrefs()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
animator.translationX(
|
||||||
|
if (hopperGravity == Gravity.TOP or Gravity.RIGHT) 0f
|
||||||
|
else ((controller.view!!.width - controller.category_hopper_frame.width) / 2).toFloat()
|
||||||
|
).withEndAction {
|
||||||
controller.category_hopper_frame.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
controller.category_hopper_frame.updateLayoutParams<CoordinatorLayout.LayoutParams> {
|
||||||
gravity =
|
gravity =
|
||||||
Gravity.TOP or (
|
Gravity.TOP or (
|
||||||
@ -66,13 +98,25 @@ class LibraryGestureDetector(private val controller: LibraryController) : Gestur
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
savePrefs()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
result = true
|
||||||
|
}
|
||||||
|
animator.start()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun savePrefs() {
|
||||||
if (!controller.hasMovedHopper) {
|
if (!controller.hasMovedHopper) {
|
||||||
controller.preferences.shownHopperSwipeTutorial().set(true)
|
controller.preferences.shownHopperSwipeTutorial().set(true)
|
||||||
}
|
}
|
||||||
controller.hopperGravity = controller.preferences.hopperGravity().get()
|
controller.hopperGravity = controller.preferences.hopperGravity().get()
|
||||||
result = true
|
controller.category_hopper_frame.translationX = 0f
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
|
private companion object {
|
||||||
|
const val SWIPE_THRESHOLD = 50
|
||||||
|
const val SWIPE_VELOCITY_THRESHOLD = 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,8 +682,8 @@ open class MainActivity : BaseActivity(), DownloadServiceListener {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val SWIPE_THRESHOLD = 100
|
private const val SWIPE_THRESHOLD = 100
|
||||||
const val SWIPE_VELOCITY_THRESHOLD = 100
|
private const val SWIPE_VELOCITY_THRESHOLD = 100
|
||||||
|
|
||||||
// Shortcut actions
|
// Shortcut actions
|
||||||
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
|
const val SHORTCUT_LIBRARY = "eu.kanade.tachiyomi.SHOW_LIBRARY"
|
||||||
|
Loading…
Reference in New Issue
Block a user