SoFunction
Updated on 2025-03-11

Android custom control ScrollView implements up and down swipe function

This article shares the specific code for Android ScrollView to implement up and down sliding function for your reference. The specific content is as follows

package ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;


public class MyScrollView extends ViewGroup {

  private int mScreeHeight;//Screen height  private Scroller mScroller;
  private int mLastY;
  private int mStart;
  private int mEnd;
  private Context context;


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

  public MyScrollView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initView(context);
  }

  public MyScrollView(Context context, AttributeSet attrs,
            int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    initView(context);
  }


  private void initView(Context context) {
    WindowManager wm = (WindowManager) (Context.WINDOW_SERVICE);
    //The DisplayMetrics class provides common information about displays, such as display size, resolution, and fonts.    DisplayMetrics dm = new DisplayMetrics();
    ().getMetrics(dm);
    mScreeHeight = ;//Height (pixel)    mScroller = new Scroller(context);
  }

  //Inheriting the method that must be implemented in ViewGroup  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childCount = getChildCount();//Get the number of subviews    //Set the height of the ViewGroup    MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
     = mScreeHeight * childCount;
    setLayoutParams(mlp);
    for (int i = 0; i < childCount; i++) {
      View child = getChildAt(i);
      if (() != ) {
        //The parameter is relative to the upper left and lower right position relative to the parent container, the third parameter must be r        (0, i * mScreeHeight, r, (i + 1) * mScreeHeight);
      }
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    (widthMeasureSpec, heightMeasureSpec);
    int count = getChildCount();
    for (int i = 0; i < count; i++) {
      View child = getChildAt(i);
      measureChild(child, widthMeasureSpec, heightMeasureSpec);
    }
  }

  @Override
  public boolean onTouchEvent(MotionEvent event) {
    int y = (int) ();//Relative to the y value of view, getRawY() is relative to the screen    switch (()) {
      case MotionEvent.ACTION_DOWN:
        mLastY = y;//The last y value        mStart = getScrollY();//Record the touch starting point        break;
      case MotionEvent.ACTION_MOVE:
        if(!()) {
          ();//Give up moving to the final position        }
        int dy = mLastY - y;//Offset distance        //If the sliding distance is less than 0 or greater than the screen height, no offset        if(getScrollY()<0){
          dy = 0;
        }
        if(getScrollY() > getHeight()-mScreeHeight){
          dy = 0;
        }
        scrollBy(0,dy);//move        mLastY = y;
        break;
      case MotionEvent.ACTION_UP:
        int dScrollY = checkAlignment();//The distance of overall movement        if(dScrollY > 0){
          if(dScrollY < mScreeHeight / 3){
            (0,getScrollY(),0,-dScrollY);
          }else{
            (0,getScrollY(),0,mScreeHeight-dScrollY);
          }
        }else{
          if(-dScrollY < mScreeHeight / 3){
            (0,getScrollY(),0,-dScrollY);
          }else{
            (0,getScrollY(),0,-mScreeHeight-dScrollY);
          }
        }
        break;
    }
    postInvalidate();
    return true;
  }

  private int checkAlignment(){
     mEnd = getScrollY();//Record touch end point    boolean isUp = ((mEnd - mStart)>0) ? true : false;
    int lastPrev = mEnd % mScreeHeight;
    int lastNext = mScreeHeight - lastPrev;
    if(isUp){
      return lastPrev;//up    }else
      return -lastNext;
  }

  @Override
  public void computeScroll() {
    ();
    if(()){//Return true, indicating that the move has not been completed yet      scrollTo(0,());//Move to current location      postInvalidate();
      //invalidate() is used to refresh the View and must be done in the UI thread.      //postInvalidate() can be called in non-UI thread    }
  }
}

Knowledge points:

1. Get the screen parameter code:

DisplayMetrics metric = new DisplayMetrics(); 
// Used after API 17, the acquired pixel width and height contain the space occupied by virtual keys, and is obtained by reflection before API 17().getDefaultDisplay().getRealMetrics(metric); 
//The pixel width and height obtained do not contain the space occupied by the virtual key//().getDefaultDisplay().getMetrics(metric); 
int width = ; // Width (pixels)int height = ; // Height (pixel)float density = ; // dp scaling factorint densityDpi = ; // Generalized densityfloat xdpi = ;//The true density of the x-axis directionfloat ydpi = ;//The true density of the y-axis direction

The screen height value contains the pixels of the status bar. The real Activity height in non-immersion mode needs to be subtracted from the status bar height. Get the status bar height code:

private int getStatusBarHeight() { 
  Rect rect = new Rect(); 
  getWindow().getDecorView().getWindowVisibleDisplayFrame(rect); 
  return ; 
} 

The values ​​of the screen parameters Width and Height are related to the screen direction, while the other 4 values ​​are not related to the screen direction.

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.