温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android中如何通过自定义ViewGroup实现一个弹性滑动效果

发布时间:2022-04-08 16:58:45 来源:亿速云 阅读:272 作者:iii 栏目:编程语言

本篇内容主要讲解“Android中如何通过自定义ViewGroup实现一个弹性滑动效果”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android中如何通过自定义ViewGroup实现一个弹性滑动效果”吧!

实现原理

onMeasure()中测量所有子View

 @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   // 测量所有子View   int count = getChildCount();   for (int i = 0; i < count; i++) {    View childView = getChildAt(i);    measureChild(childView, widthMeasureSpec, heightMeasureSpec);   }   setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);  }

onLayout()中,将所有的子View按照位置依次往下排列

@Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {   // 设置ViewGroup的高度,对所有子View进行排列   int childCount = getChildCount();   MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();   params.height = mScreenHeight * childCount;   for (int i = 0; i < childCount; i++) {    View childView = getChildAt(i);    if (childView.getVisibility() != View.GONE) {     // 给每个ChildView放置在指定位置     childView.layout(l, i * mScreenHeight, r, (i + 1) * mScreenHeight);    }   }  }

onTouchEvent()中处理滑动

 @Override  public boolean onTouchEvent(MotionEvent event) {   switch (event.getAction()) {    case MotionEvent.ACTION_DOWN:     mLastY = (int) event.getY();     mStart = getScrollY();     return true;    case MotionEvent.ACTION_MOVE:     if (!mScroller.isFinished()) {      // 终止滑动      mScroller.abortAnimation();     }     int offsetY = (int) (mLastY - event.getY());     Log.d(TAG, "onTouchEvent: getScrollY: " + getScrollY());     Log.d(TAG, "onTouchEvent: offsetY " + offsetY);     // 到达顶部,使用offset判断方向     if (getScrollY() + offsetY < 0) { // 当前已经滑动的 Y 位置      offsetY = 0;     }     // 到达底部     if (getScrollY() > getHeight() - mScreenHeight && offsetY > 0) {      offsetY = 0;     }     scrollBy(0, offsetY);     // 滑动完成后,重新设置LastY位置     mLastY = (int) event.getY();     break;    case MotionEvent.ACTION_UP:     mEnd = getScrollY();     int distance = mEnd - mStart;     if (distance > 0) { // 向上滑动      if (distance < mScreenHeight / 3) {       Log.d(TAG, "onTouchEvent: distance < screen/3");       // 回到原来位置       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       // 滚到屏幕的剩余位置       mScroller.startScroll(0, getScrollY(), 0, mScreenHeight - distance);      }     } else {    // 向下滑动      if (-distance < mScreenHeight / 3) {       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       mScroller.startScroll(0, getScrollY(), 0, -mScreenHeight - distance);      }     }     postInvalidate();   }   return super.onTouchEvent(event);  }

其中ACTION_UP这段代码是处理弹性滑动的

case MotionEvent.ACTION_UP:     mEnd = getScrollY();     int distance = mEnd - mStart;     if (distance > 0) { // 向上滑动      if (distance < mScreenHeight / 3) {       Log.d(TAG, "onTouchEvent: distance < screen/3");       // 回到原来位置       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       // 滚到屏幕的剩余位置       mScroller.startScroll(0, getScrollY(), 0, mScreenHeight - distance);      }     } else {    // 向下滑动      if (-distance < mScreenHeight / 3) {       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       mScroller.startScroll(0, getScrollY(), 0, -mScreenHeight - distance);      }     }     postInvalidate();

完整代码

public class ScrollViewGroup extends ViewGroup {  private static final String TAG = "ScrollView";  private Scroller mScroller;  private int mScreenHeight; // 窗口高度  private int mLastY;  private int mStart;  private int mEnd;  public ScrollViewGroup(Context context) {   this(context, null);  }  public ScrollViewGroup(Context context, AttributeSet attrs) {   this(context, attrs, 0);  }  public ScrollViewGroup(Context context, AttributeSet attrs, int defStyleAttr) {   super(context, attrs, defStyleAttr);   mScroller = new Scroller(context);   // 获取屏幕高度   WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);   DisplayMetrics metrics = new DisplayMetrics();   windowManager.getDefaultDisplay().getMetrics(metrics);   mScreenHeight = metrics.heightPixels;   Log.d(TAG, "ScrollViewGroup: ScreenHeight " + mScreenHeight);  }  @Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {   // 测量所有子View   int count = getChildCount();   for (int i = 0; i < count; i++) {    View childView = getChildAt(i);    measureChild(childView, widthMeasureSpec, heightMeasureSpec);   }   setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);  }  @Override  protected void onLayout(boolean changed, int l, int t, int r, int b) {   // 设置ViewGroup的高度,对所有子View进行排列   int childCount = getChildCount();   MarginLayoutParams params = (MarginLayoutParams) getLayoutParams();   params.height = mScreenHeight * childCount;   for (int i = 0; i < childCount; i++) {    View childView = getChildAt(i);    if (childView.getVisibility() != View.GONE) {     // 给每个ChildView放置在指定位置     childView.layout(l, i * mScreenHeight, r, (i + 1) * mScreenHeight);    }   }  }  @Override  public boolean onTouchEvent(MotionEvent event) {   switch (event.getAction()) {    case MotionEvent.ACTION_DOWN:     mLastY = (int) event.getY();     mStart = getScrollY();     return true;    case MotionEvent.ACTION_MOVE:     if (!mScroller.isFinished()) {      // 终止滑动      mScroller.abortAnimation();     }     int offsetY = (int) (mLastY - event.getY());     Log.d(TAG, "onTouchEvent: getScrollY: " + getScrollY());     Log.d(TAG, "onTouchEvent: offsetY " + offsetY);     // 到达顶部,使用offset判断方向     if (getScrollY() + offsetY < 0) { // 当前已经滑动的 Y 位置      offsetY = 0;     }     // 到达底部     if (getScrollY() > getHeight() - mScreenHeight && offsetY > 0) {      offsetY = 0;     }     scrollBy(0, offsetY);     // 滑动完成后,重新设置LastY位置     mLastY = (int) event.getY();     break;    case MotionEvent.ACTION_UP:     mEnd = getScrollY();     int distance = mEnd - mStart;     if (distance > 0) { // 向上滑动      if (distance < mScreenHeight / 3) {       Log.d(TAG, "onTouchEvent: distance < screen/3");       // 回到原来位置       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       // 滚到屏幕的剩余位置       mScroller.startScroll(0, getScrollY(), 0, mScreenHeight - distance);      }     } else {    // 向下滑动      if (-distance < mScreenHeight / 3) {       mScroller.startScroll(0, getScrollY(), 0, -distance);      } else {       mScroller.startScroll(0, getScrollY(), 0, -mScreenHeight - distance);      }     }     postInvalidate();   }   return super.onTouchEvent(event);  }  @Override  public void computeScroll() {   if (mScroller.computeScrollOffset()) {    scrollTo(mScroller.getCurrX(), mScroller.getCurrY());    postInvalidate();   }  } }

到此,相信大家对“Android中如何通过自定义ViewGroup实现一个弹性滑动效果”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI