Android Custom Control ScrollView Realizes Up and Down Sliding Function

  • 2021-09-20 21:28:41
  • OfStack

This article example for everyone to share Android ScrollView to achieve up and down sliding function of the specific code, for your reference, the specific content is as follows


package com.example.zhuang;

import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Scroller;


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.getSystemService(Context.WINDOW_SERVICE);
    //DisplayMetrics  Class provides the 1 General information about display, such as display size, resolution and font. 
    DisplayMetrics dm = new DisplayMetrics();
    wm.getDefaultDisplay().getMetrics(dm);
    mScreeHeight = dm.heightPixels;// Height (pixels) 
    mScroller = new Scroller(context);
  }

  // Inheritance ViewGroup Methods that must be implemented 
  @Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int childCount = getChildCount();// Acquirer view The number of 
    // Settings ViewGroup The height of 
    MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
    mlp.height = mScreeHeight * childCount;
    setLayoutParams(mlp);
    for (int i = 0; i < childCount; i++) {
      View child = getChildAt(i);
      if (child.getVisibility() != View.GONE) {
        // Parameter is the upper left and lower right position relative to the parent container , No. 1 3 Parameters must be r
        child.layout(0, i * mScreeHeight, r, (i + 1) * mScreeHeight);
      }
    }
  }

  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(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) event.getY();// Relative to view Adj. y Value, getRawY() Is the relative screen 
    switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN:
        mLastY = y;// Upper 1 Secondary y Value 
        mStart = getScrollY();// Record the starting point of touch 
        break;
      case MotionEvent.ACTION_MOVE:
        if(!mScroller.isFinished()) {
          mScroller.abortAnimation();// Give up and move to the final position 
        }
        int dy = mLastY - y;// Offset distance 
        // If the sliding distance is less than 0 Or greater than the screen height, without offset 
        if(getScrollY()<0){
          dy = 0;
        }
        if(getScrollY() > getHeight()-mScreeHeight){
          dy = 0;
        }
        scrollBy(0,dy);// Moving 
        mLastY = y;
        break;
      case MotionEvent.ACTION_UP:
        int dScrollY = checkAlignment();// Distance of overall movement 
        if(dScrollY > 0){
          if(dScrollY < mScreeHeight / 3){
            mScroller.startScroll(0,getScrollY(),0,-dScrollY);
          }else{
            mScroller.startScroll(0,getScrollY(),0,mScreeHeight-dScrollY);
          }
        }else{
          if(-dScrollY < mScreeHeight / 3){
            mScroller.startScroll(0,getScrollY(),0,-dScrollY);
          }else{
            mScroller.startScroll(0,getScrollY(),0,-mScreeHeight-dScrollY);
          }
        }
        break;
    }
    postInvalidate();
    return true;
  }

  private int checkAlignment(){
     mEnd = getScrollY();// Record the end point of touch 
    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() {
    super.computeScroll();
    if(mScroller.computeScrollOffset()){// Return true Indicates that the movement has not been completed 
      scrollTo(0,mScroller.getCurrY());// Move to the current position 
      postInvalidate();
      //invalidate() Is used to refresh View Of, must be in UI Thread. 
      //postInvalidate() Can be in non- UI Thread invocation 
    }
  }
}

Knowledge points:

1. Get the screen parameter code:


DisplayMetrics metric = new DisplayMetrics(); 
//API 17 Used later, the obtained pixel width and height contains the space occupied by the virtual key, which is used in the API 17 Previously acquired by reflection  
context.getWindowManager().getDefaultDisplay().getRealMetrics(metric); 
// The obtained pixel width and height does not include the space occupied by the virtual key  
//context.getWindowManager().getDefaultDisplay().getMetrics(metric); 
int width = metric.widthPixels; //  Width (pixels)  
int height = metric.heightPixels; //  Height (pixels)  
float density = metric.density; // dp Scale factor  
int densityDpi = metric.densityDpi; //  Generalized density  
float xdpi = metric.xdpi;//x True density in axial direction  
float ydpi = metric.ydpi;//y True density in axial direction  

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


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

The values of screen parameters Width and Height are related to screen orientation, and the other four values are independent of screen orientation.


Related articles: