Android中如何通过自定义ViewGroup实现一个弹性滑动效果
发表于:2025-11-13 作者:千家信息网编辑
千家信息网最后更新 2025年11月13日,本篇内容主要讲解"Android中如何通过自定义ViewGroup实现一个弹性滑动效果",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"Android中如何通
千家信息网最后更新 2025年11月13日Android中如何通过自定义ViewGroup实现一个弹性滑动效果
本篇内容主要讲解"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实现一个弹性滑动效果"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
位置
弹性
屏幕
高度
效果
剩余
测量
代码
内容
方向
顶部
处理
学习
实用
更深
兴趣
原理
实用性
实际
操作简单
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
x86服务器的cpu数量配置
数据库系统的安全措施
高淳区网络技术服务
163smtp服务器
普通人学软件开发要多久
欧洲网络安全事件
网络安全曾东
2021中职网络安全大赛
事业单位网络安全风险点
初级软件开发师薪水
触发数据库的增删改查是什么功能
软件开发专业需要学习什么
连接linux达梦数据库
自学杀毒软件开发
美军软件开发商
湖南医疗软件开发
好惠搜网络技术有限公司
河南农业大学软件开发
如何成为助理网络安全工程师
网络安全 社交安全心得
江阴智能软件开发市场价格
桌面程序数据库
服务器管理口地址
网络安全组整改情况报告
nc软件开发工程师
网络安全 全员 培训
数据库视图的更名和删除
网络文明网络安全征文500字
车载网络技术期末考试
峰会期间网络安全通知