Reduce horizontal swipe sensitivity in timelines (#3148)
* Reduce horizontal swipe sensitivity in timelines Fixes https://github.com/tuskyapp/Tusky/issues/2725, fixes https://github.com/tuskyapp/Tusky/issues/2112, fixes https://github.com/tuskyapp/Tusky/issues/2530, fixes https://github.com/tuskyapp/Tusky/issues/2200, fixes https://github.com/tuskyapp/Tusky/issues/2176, fixes https://github.com/tuskyapp/Tusky/issues/2112, fixes https://github.com/tuskyapp/Tusky/issues/1912, fixes https://github.com/tuskyapp/Tusky/issues/1718, fixes https://github.com/tuskyapp/Tusky/issues/1336 * Set scale factor to 4 * Catch exceptions, just in case
This commit is contained in:
parent
e5e076b0d3
commit
d6e7905e01
4 changed files with 44 additions and 0 deletions
|
@ -89,6 +89,7 @@ import com.keylesspalace.tusky.util.deleteStaleCachedMedia
|
||||||
import com.keylesspalace.tusky.util.emojify
|
import com.keylesspalace.tusky.util.emojify
|
||||||
import com.keylesspalace.tusky.util.getDimension
|
import com.keylesspalace.tusky.util.getDimension
|
||||||
import com.keylesspalace.tusky.util.hide
|
import com.keylesspalace.tusky.util.hide
|
||||||
|
import com.keylesspalace.tusky.util.reduceSwipeSensitivity
|
||||||
import com.keylesspalace.tusky.util.show
|
import com.keylesspalace.tusky.util.show
|
||||||
import com.keylesspalace.tusky.util.updateShortcut
|
import com.keylesspalace.tusky.util.updateShortcut
|
||||||
import com.keylesspalace.tusky.util.viewBinding
|
import com.keylesspalace.tusky.util.viewBinding
|
||||||
|
@ -253,6 +254,8 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidInje
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.viewPager.reduceSwipeSensitivity()
|
||||||
|
|
||||||
setupDrawer(savedInstanceState, addSearchButton = hideTopToolbar)
|
setupDrawer(savedInstanceState, addSearchButton = hideTopToolbar)
|
||||||
|
|
||||||
/* Fetch user info while we're doing other things. This has to be done after setting up the
|
/* Fetch user info while we're doing other things. This has to be done after setting up the
|
||||||
|
|
|
@ -78,6 +78,7 @@ import com.keylesspalace.tusky.util.getDomain
|
||||||
import com.keylesspalace.tusky.util.hide
|
import com.keylesspalace.tusky.util.hide
|
||||||
import com.keylesspalace.tusky.util.loadAvatar
|
import com.keylesspalace.tusky.util.loadAvatar
|
||||||
import com.keylesspalace.tusky.util.parseAsMastodonHtml
|
import com.keylesspalace.tusky.util.parseAsMastodonHtml
|
||||||
|
import com.keylesspalace.tusky.util.reduceSwipeSensitivity
|
||||||
import com.keylesspalace.tusky.util.setClickableText
|
import com.keylesspalace.tusky.util.setClickableText
|
||||||
import com.keylesspalace.tusky.util.show
|
import com.keylesspalace.tusky.util.show
|
||||||
import com.keylesspalace.tusky.util.viewBinding
|
import com.keylesspalace.tusky.util.viewBinding
|
||||||
|
@ -235,6 +236,7 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
|
||||||
// Setup the tabs and timeline pager.
|
// Setup the tabs and timeline pager.
|
||||||
adapter = AccountPagerAdapter(this, viewModel.accountId)
|
adapter = AccountPagerAdapter(this, viewModel.accountId)
|
||||||
|
|
||||||
|
binding.accountFragmentViewPager.reduceSwipeSensitivity()
|
||||||
binding.accountFragmentViewPager.adapter = adapter
|
binding.accountFragmentViewPager.adapter = adapter
|
||||||
binding.accountFragmentViewPager.offscreenPageLimit = 2
|
binding.accountFragmentViewPager.offscreenPageLimit = 2
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.keylesspalace.tusky.components.search.adapter.SearchPagerAdapter
|
||||||
import com.keylesspalace.tusky.databinding.ActivitySearchBinding
|
import com.keylesspalace.tusky.databinding.ActivitySearchBinding
|
||||||
import com.keylesspalace.tusky.di.ViewModelFactory
|
import com.keylesspalace.tusky.di.ViewModelFactory
|
||||||
import com.keylesspalace.tusky.settings.PrefKeys
|
import com.keylesspalace.tusky.settings.PrefKeys
|
||||||
|
import com.keylesspalace.tusky.util.reduceSwipeSensitivity
|
||||||
import com.keylesspalace.tusky.util.viewBinding
|
import com.keylesspalace.tusky.util.viewBinding
|
||||||
import dagger.android.DispatchingAndroidInjector
|
import dagger.android.DispatchingAndroidInjector
|
||||||
import dagger.android.HasAndroidInjector
|
import dagger.android.HasAndroidInjector
|
||||||
|
@ -62,6 +63,7 @@ class SearchActivity : BottomSheetActivity(), HasAndroidInjector {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupPages() {
|
private fun setupPages() {
|
||||||
|
binding.pages.reduceSwipeSensitivity()
|
||||||
binding.pages.adapter = SearchPagerAdapter(this)
|
binding.pages.adapter = SearchPagerAdapter(this)
|
||||||
|
|
||||||
val enableSwipeForTabs = preferences.getBoolean(PrefKeys.ENABLE_SWIPE_FOR_TABS, true)
|
val enableSwipeForTabs = preferences.getBoolean(PrefKeys.ENABLE_SWIPE_FOR_TABS, true)
|
||||||
|
|
|
@ -18,8 +18,11 @@ package com.keylesspalace.tusky.util
|
||||||
|
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import androidx.viewpager2.widget.ViewPager2
|
||||||
|
|
||||||
fun View.show() {
|
fun View.show() {
|
||||||
this.visibility = View.VISIBLE
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue