Solution of Jitter Problem in AppbarLayout Sliding Process

The need for an iteration is to achieve a hover effect on the page, considering that CoordinatorLayout has passed a number of versions of BugFix, it should be relatively stable. So try to implement hover directly with CoordinatorLayout+AppBarLayout. As the type of head layout continues to increase, the length gradually becomes larger, so the problem is unexpectedly discovered during the sliding process. Since the official is not repaired, the problem can only be repaired using the custom Behavior.

Problem

When the Header part is in the upward fling process, if the finger makes a fling in the opposite direction to the underlying Recylerview, Scrollview, etc., the screen shakes, as shown in the figure below.

appbarBehavior

Solution

In the Support package version 28 or AndroidX package, the custom AppbarLayout Behavoir is as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Suppress("unused")
class FixScrollShakeBehavior : Behavior {

constructor()
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)


override fun onInterceptTouchEvent(parent: CoordinatorLayout, child: AppBarLayout, ev: MotionEvent): Boolean {
if (ev.action == ACTION_DOWN) {
val scroller = getScrollerObj()
if (scroller is OverScroller) {
scroller.abortAnimation()
}
}
return super.onInterceptTouchEvent(parent, child, ev)
}

private fun getScrollerObj(): Any? {
var obj: Any? = null
try {
val field = this.javaClass.superclass?.superclass?.superclass?.getDeclaredField("scroller")
field?.isAccessible = true
obj = field?.get(this)
} catch (e: Exception) {
e.printStackTrace()
}
return obj
}
}

In the package with Support version 27, the corresponding scroller is mScroller, and its parent class level is one less layer. Others are the same as the above solution.