SoFunction
Updated on 2025-03-11

Android Custom View Elastic Scroller Detailed Explanation

This article shares the specific code of Android elastic sliding Scroller for your reference. The specific content is as follows

What is Scroller

Scroller is a sliding help class. It cannot make the View really slide, but cooperates with scrollTo/ScrollBy to make the View slide slowly and produce animation effects. In fact, it is the same principle as attribute animation. In my opinion, the translation effect of Scroller and attribute animation is the same.

How to use

 //① Example of a Scroller, it has three constructs as follows  //public Scroller (Context context)
  //public Scroller (Context context, Interpolator interpolator)//Pass in a time interpolator  //public Scroller (Context context, Interpolator interpolator, boolean flywheel)
  Scroller mScroller=new Scroller(context);

  //②Use Scroller  //startScroll() passes in some parameters: start position, end position, start time slide to end position.  (int startX,int startY,int endx,int endY,int duration);
  invalidate();//In ViewGroup, the invalidate() method will cause the execution of the computeScroll() method
  //③ In the computeScroll() method, determine whether mScroller is ending. If it does not end, call scrollTo() to put the view in the correct position.  @Override
  public void computeScroll() {
   //computeScrollOffset() determines whether it is still scrolling. If it is still scrolling, it will get the position where the view should be at a certain moment, refresh the values ​​of mCurrX and mCurrY in the Scroller, and return true;   if (()) {
    scrollTo((), ());
    //Update the interface    postInvalidate();
   }
   ();
  }

Example of usage:

package ;

/**
  * Scroller practice, a simple ViewPager
  * @author : liujian
  * @since : 2017/12/17
  */

public class ScrollLayout extends ViewGroup {
 private Scroller mScroller;
 //The minimum distance of the current device sliding private int mTouchSlop;

 private int leftBorder;//The left boundary of the layout content private int rightBorder;//The right boundary of the layout content
 private float mRawXDown;
 private float mRawXMove;
 private float mRawXLastMove;

 public ScrollLayout(Context context) {
  super(context);
  initView(context);
 }

 public ScrollLayout(Context context, @Nullable AttributeSet attrs) {
  super(context, attrs);
  initView(context);
 }

 public ScrollLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  initView(context);
 }

 private void initView(Context context) {
  mTouchSlop = (getContext()).getScaledTouchSlop();
  mScroller = new Scroller(getContext());
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  (widthMeasureSpec, heightMeasureSpec);
  // Give a recommended measurement size and measurement mode for a subView in ScrollLayout  measureChildren(widthMeasureSpec, heightMeasureSpec);
 }

 @Override
 protected void onLayout(boolean changed, int l, int t, int r, int b) {
  int childCount = getChildCount();
  for (int i = 0; i < childCount; i++) {
   View view = getChildAt(i);
   (i * (), 0, (i + 1) * (), ());
  }
  leftBorder = getChildAt(0).getLeft();
  rightBorder = getChildAt(getChildCount() - 1).getRight();
 }

 @Override
 public boolean onInterceptTouchEvent(MotionEvent ev) {
  switch (()) {
   case MotionEvent.ACTION_DOWN:
    mRawXDown = ();
    mRawXLastMove = mRawXDown;
    break;
   case MotionEvent.ACTION_MOVE:
    mRawXMove = ();
    mRawXLastMove = mRawXMove;
    float distance = (mRawXMove - mRawXDown);
    //When sliding left and right, intercepting the touch event of the subview    if (distance > mTouchSlop) {
     return true;
    }
    break;
   case MotionEvent.ACTION_UP:
    break;
  }
  return (ev);
 }

 @SuppressLint("ClickableViewAccessibility")
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  switch (()) {
   case MotionEvent.ACTION_MOVE:
    mRawXMove = ();
    int distanceX = (int) (mRawXLastMove - mRawXMove);
    //Treatment of boundary exceptions    if (getScrollX() + distanceX < leftBorder) {
     scrollBy(leftBorder, 0);
    }
    if (getScrollX() + getWidth() + distanceX > rightBorder) {
     scrollBy(rightBorder - getWidth(), 0);
    }
    scrollBy(distanceX, 0);
    mRawXLastMove = mRawXMove;
    break;
   case MotionEvent.ACTION_UP:
    //The current page    int targetIndex = (getScrollX() + getWidth() / 2) / getWidth();
    int dx = targetIndex * getWidth() - getScrollX();
    ("TAG", "dx: " + dx);
    ("TAG", "getScrollX: " + getScrollX());
    ("TAG", "getWidth: " + getWidth());

    // The second step is to call the startScroll() method to initialize the rolling data and refresh the interface    (getScrollX(), 0, dx, 0);
    invalidate();
    break;
  }
  return (event);
 }

 @Override
 public void computeScroll() {
  if (()) {
   scrollTo((), ());
   invalidate();
  }
 }
}

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.