文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android继承ViewGroup如何实现Scroll滑动效果

2023-05-30 21:52

关注

这篇文章主要介绍Android继承ViewGroup如何实现Scroll滑动效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

具体如下:

extends ViewGroup需要重写onMeasure和onLayout方法

onMeasure方法是去测量ViewGroup需要的大小以及包含的子View需要的大小。

执行完上面的方法后,再执行onLayout方法去设置子View的摆放位置。

实现Scroll滑动效果需要去检测滑动速率,即要知道每个单位时间滑动了多少像素值,根据这个像素值去判断Scroll滑动到下一页还是上一页。

Android为我们提供了VelocityTracker这个类检测速率

使用mVelocityTracker = VelocityTracker.obtain();来初始化

使用mVelocityTracker.addMovement(event);将touch事件添加进去检测。注意每个touch事件都要添加进去

使用mVelocityTracker.computeCurrentVelocity(1000);计算每个单位时间内滑动了多少像素,这里传入的是1000ms即1s。

然后使用float pxsec = mVelocityTracker.getXVelocity();获取到x轴滑动的像素值,必须在执行了上面方法只会再调用。

最后需要mVelocityTracker.recycle();mVelocityTracker = null;回收掉这个对象。

完整代码是:

public class MyScrollLayout extends ViewGroup{ private int curScreen; private int defaultScreen = 0; private Scroller mScroller; private float mLastMotionX = 0; private VelocityTracker mVelocityTracker; public MyScrollLayout(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(context); } public MyScrollLayout(Context context, AttributeSet attrs) {  super(context, attrs);  init(context); } public MyScrollLayout(Context context) {  super(context);  init(context); } private void init(Context context){  curScreen = defaultScreen;  mScroller = new Scroller(context); } @Override public void computeScroll() {  if(mScroller.computeScrollOffset()){   scrollTo(mScroller.getCurrX(), mScroller.getCurrY());   postInvalidate();  } } @Override public boolean onTouchEvent(MotionEvent event) {  // TODO Auto-generated method stub  int action = event.getAction();  float x = event.getX();  switch (action) {  case MotionEvent.ACTION_DOWN:   if(mVelocityTracker==null){    mVelocityTracker = VelocityTracker.obtain();    mVelocityTracker.addMovement(event);   }   if(!mScroller.isFinished()){    mScroller.abortAnimation();   }   mLastMotionX = event.getX();   break;  case MotionEvent.ACTION_MOVE:   float delt = mLastMotionX-x;   if(isCanMove((int)delt)){   if(mVelocityTracker!=null){    mVelocityTracker.addMovement(event);   }   mLastMotionX = x;   scrollBy((int)delt, 0);   }   break;  case MotionEvent.ACTION_UP:   if(mVelocityTracker!=null){    mVelocityTracker.addMovement(event);    mVelocityTracker.computeCurrentVelocity(1000);    float pxsec = mVelocityTracker.getXVelocity();    if(pxsec>600 && curScreen >0){     snapToScreen(curScreen-1);    }else if(pxsec<-600 && curScreen<getChildCount()-1){     snapToScreen(curScreen+1);    }else{     //主要是用来获取该滑动到哪个界面,最终调用的是invalid调用draw方法然后draw调用computeScroll方法,然后使用scroller对象     snapToDestination();    }    mVelocityTracker.recycle();    mVelocityTracker = null;   }   break;  default:   break;  }  return true; } private void snapToScreen(int screen){  int whichscreen = Math.max(0, Math.min(screen, getChildCount()-1));  if(getScrollX()!=(whichscreen*getWidth())){   final int delat = whichscreen*getWidth() - getScrollX();   mScroller.startScroll(getScrollX(), 0, delat, 0, Math.abs(delat)*2);   curScreen = whichscreen;   invalidate();  } } private void snapToDestination(){  int screen = (getScrollX()+getWidth()/2)/getWidth();  snapToScreen(screen); } private boolean isCanMove(int delat){    if(getScrollX()>=(getChildCount()-1)*getWidth() && delat>0){   return false;  }  return true; } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) {  if(changed){  int totalHeight = 0;  int totalwidth = 0;  int childCount = getChildCount();  for(int i=0; i<childCount; i++){   View childView = getChildAt(i);   int childwidth = childView.getMeasuredWidth();   int childheight = childView.getMeasuredHeight();   childView.layout(totalwidth, t, totalwidth+childwidth, b);   totalHeight += childheight;   totalwidth += childwidth;  }  } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  // TODO Auto-generated method stub  measureChildren(widthMeasureSpec, heightMeasureSpec);  super.onMeasure(widthMeasureSpec, heightMeasureSpec); }}

很多人会以为ViewGroup的滑动是Scroller的功劳,其实不然,Scroller在这里扮演的角色我认为更像是一个用来计算x和y轴单位时间移动像素的工具类而已,仅此而已没有特别的能力。

真正在这里实现Scroll滑动效果的是ViewGroup里的scrollto和scrollby方法,scrollto是滑动到,scrollby是滑动了。

Scroller.startScroll(getScrollX(), 0, delat, 0, Math.abs(delat)*2);

Scroller这个类的startScroll方法传入了五个参数,分别对应,x轴起滑的偏移像素,y轴起滑的偏移像素,x轴滑动像素,y轴滑动像素,滑动过程需要的时间。

看源码如果不传时间参数的方法有个默认的时间250ms。

scroller.startScroll之后需要调用invalidate方法,然后调用ViewGroup的draw方法,然后调用computeScroll方法,在computeScroll方法里面调用Scroller.computeScrollOffset()方法去判断有没有计算完,没计算完返回true,然后scrollto方法,再postInvalidate();方法重新执行computeScroll方法。

以上是“Android继承ViewGroup如何实现Scroll滑动效果”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网行业资讯频道!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯