Nik Clayton 2023-01-13 19:51:09 +01:00 committed by GitHub
commit d6e7905e01
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 0 deletions

View file

@ -18,8 +18,11 @@ package com.keylesspalace.tusky.util
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.View
import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
fun View.show() {
this.visibility = View.VISIBLE
@ -63,3 +66,37 @@ inline fun EditText.afterTextChanged(
}
})
}
/**
* Reduce ViewPager2's sensitivity to horizontal swipes.
*/
fun ViewPager2.reduceSwipeSensitivity() {
// ViewPager2 is very sensitive to horizontal motion when swiping vertically, and will
// trigger a page transition if the user's swipe is only a few tens of degrees off from
// vertical. This is a problem if the underlying content is a list that the user wants
// to scroll vertically -- it's far too easy to trigger an accidental horizontal swipe.
//
// One way to stop this is to reach in to ViewPager2's RecyclerView and adjust the amount
// of touch slop it has. Scaling by 2 appears to work well.
//
// See https://issuetracker.google.com/issues/139867645 and
// https://bladecoder.medium.com/fixing-recyclerview-nested-scrolling-in-opposite-direction-f587be5c1a04
// for more (the approach in that Medium article works, but is still quite sensitive to
// horizontal movement while scrolling).
try {
val recyclerViewField = ViewPager2::class.java.getDeclaredField("mRecyclerView")
recyclerViewField.isAccessible = true
val recyclerView = recyclerViewField.get(this) as RecyclerView
val touchSlopField = RecyclerView::class.java.getDeclaredField("mTouchSlop")
touchSlopField.isAccessible = true
val touchSlop = touchSlopField.get(recyclerView) as Int
// 4 seems to be a sweet-spot. 2-3 still causes a horizontal swipe right if the user drags
// down-left at ~ 45 degree angle. Experimentally, 4 requires the swipe to be +/- ~ 10 degrees
// from horizontal to register as a horizontal and not a vertical swipe.
val scaleFactor = 4
touchSlopField.set(recyclerView, touchSlop * scaleFactor)
} catch (e: Exception) {
Log.w("reduceSwipeSensitivity", e)
}
}