The use of OverScroll has been introduced previously. Students who have not read the article can first understand the implementation of elastic scroll and inertial scroll effect similar to wechat home page.

Next, the implementation principle of OverScroll is introduced.

CoordinatorLayout

CoordinatorLayout is a powerful layout container in the Support package. It is essentially a FrameLayout, but it allows developers to coordinate various sub-views through customized behaviors to achieve a variety of complex and cool UI interaction effects.

To use CoordinatorLayout you need to add the following to build.gradle:

implementation 'com. Android. Support: design: 26.1.0'
Copy the code

There are many introductory articles about CoordinatorLayout on the Internet, here the author will not repeat, the so-called practice is more than theory, this paper describes how to use CoordinatorLayout+Behavior to achieve elastic sliding and inertia sliding, from the side to understand its use principle.

This paper achieves elastic sliding and inertial sliding effects similar to wechat home page, supporting horizontal and vertical scrolling, as shown in the figure below:

Behavior

CoordinatorLayout mainly uses Behavior to coordinate sub-views. The key methods of Behavior involved here are as follows:

methods describe
boolean onStartNestedScroll(CoordinatorLayout parent, View child, View directTargetChild, View target, int nestedScrollAxes, int type) Determine whether to process based on the return valuetargetSlide occurs, generally used to determine whether to handle a slide in a certain direction.

For example,return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) ! = 0;Handles sliding in the vertical direction. Subsequent sliding events are called back to the following methods.
void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dx, int dy, int[] consumed, int type) whentargetCalled when a slide is about to occur, where interception can be done. You can modify the parametersconsumedRepresents how many pixels are consumed (blocked). For example,targetThe control itself wants to slide 100px vertically and we need to block 80pxconsumed[1] = 80, (consumed[0],consumed[1]Corresponding to the X-axis and Y-axis respectively), and finallytargetThe control actually slides only 20px.
void onNestedScroll(CoordinatorLayout, View Child, View target, INT dxConsumed, INT dyConsumed, int dxUnconsumed, Int dyUnconsumed, int type) targetControl is called after sliding, dyConsumed is the actual consumed distance and dyUnconsumed is the unconsumed distance. Like the slide above, at this pointdyConsumed = 20.dxUnconsumed = 0If thedyConsumed = 15.dxUnconsumed = 5saidtargetWe reach the boundary by sliding 15px, which we can usedxUnconsumedHandle some out-of-bounds slippage.
boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) User quick swipetargetAnd release the finger before an inertial slide occurs, returntrueIntercepts the inertial slip event.
void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int type) All slides stop after call.

The principle of analysis

Both elastic sliding and inertial sliding belong to Over scroll, that is, to continue sliding after reaching the boundary of normal sliding range. Therefore, we only need to deal with the out-of-bounds sliding effect when reaching the boundary. The key processing logic is as follows:

The figure above describes the key logic that needs to be processed during the downward slide, and the same goes for the upward slide.

We also have to deal with inertial sliding, which allows the list to slip a little distance as it reaches the boundary while fast sliding produces the Fling event. In this case, the OverScroller tool class provided by the system is needed. Parameters related to inertial sliding in onNestedPreFling are passed into the OverScroller.


public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY) {
    if (child == target) {
        mOverScroller.fling(0.0.0, (int) velocityY, 0.0, Integer.MIN_VALUE, Integer.MAX_VALUE);
    }
    return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
}
Copy the code

Behind can. In the process of sliding through mOverScroller getCurrVelocity () gets the current time of inertia sliding speed, when the speed is less than a certain value to stop sliding.

In the key method parameters of Behavior, there is basically a type value at the end, which is explained by the document as the type of input which cause this scroll event, that is, the source of the event that generates the current slide. Type == ViewCompat.TYPE_TOUCH indicates slides caused by user touch controls, and type == ViewCompat.TYPE_NON_TOUCH indicates slides caused by non-touch controls, such as slides caused by inertia.

Therefore, in the sliding process, we can judge whether the current sliding is inertial sliding by type.

public void onNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
                           int type) {
    if (type == ViewCompat.TYPE_TOUCH) { // scroll
        
    } else { // fling}}Copy the code

Finally, we need to bounce the list back to its original position if it is out of bounds when we stop sliding, using ValueAnimator.

Code implementation

  • Elastic sliding and inertial sliding need some parameters to control the sliding effect, such as the maximum sliding distance, the minimum speed of inertial sliding, sliding damping factor, etc. Therefore, we need to define an interface, and the subview bound to ‘Behavior ‘must implement this interface. Please refer to IOverScrollCallback for interface definition. The default implementation for SimpleOverScrollCallback.

  • Custom behaviors of elastic sliding and inertia, the base class for BaseOverScrollBehavior, control the vertical scroll OverScrollVerticalBehavior, control the horizontal scroll OverScrollHorizontalBehavior.

  • Let NestedScrolling sliding controls (such as RecyclerView, NestedScrollView) implement IOverScrollCallback, provide the related parameters of sliding, here in OverScrollScrollView controls, for example, See OverScrollScrollView for the code.

Effect (layout related: NestedScrollFragment, layout_scrollView.xml) :

The project addressOverScroll

Thanks for supporting my Github project >>>OverScroll!