【Android API】3.ViewPager的实现原理和源码分析
来源:互联网 发布:oracle网络 编辑:程序博客网 时间:2024/04/29 15:32
【★☆☆☆☆】ViewPager是我们常见的控件之一了,而理解ViewPager的实现原理可以让我们后面实现自定义的滑动控件更容易。
在学习本节之前建议先自己实现前两篇文章的效果。
- 【自定义View】1.View的滑动
- 【自定义View】2.Android滑动侧边栏SlidingMenu的原理
ViewPager的开始流程是从setAdapter()开始,我们这里就不贴源码了,最好的方式是自己去看一遍源码,然后debug一遍,自己一步步走一遍。
ViewPager重写了onMeasure(),我们来看看onMeasure的主要实现
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = View.getDefaultSize(0, widthMeasureSpec); int height = View.getDefaultSize(0, heightMeasureSpec); setMeasuredDimension(width, height); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View childAt = getChildAt(i); int spec_w = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); int spec_h = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); childAt.measure(spec_w, spec_h); } }
里面其实就是测量的子View。然后就是onLayout()。
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); int width = r - l; for (int i = 0; i < childCount; i++) { View childAt = getChildAt(i); int left = l + width * i; childAt.layout(left, t, left + childAt.getMeasuredWidth(), t + childAt.getMeasuredHeight()); } }
这里很关键,实际上就是将子View横向一字排开,有点有点像横向的LinearLayout。下面就是关键一步,重写onTouchEvent(),使ViewPager实现滑动,那么我们如何实现滑动呢?我们可以用scrollTo将内容滑动。
public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: rawX = event.getRawX(); break; case MotionEvent.ACTION_MOVE: int dx = (int) (event.getRawX() - rawX); int x = getScrollX() - dx; scrollTo(x, 0); rawX = event.getRawX(); break; case MotionEvent.ACTION_UP: break; } return true; }
有了上面的代码,我们就能让ViewPager的内容滑动了,上面这些代码也是ViewPager实现的骨干代码。另外我们可以加上限制条件,不让它滚动出显示的区域,然后再MotionEvent.ACTION_UP里用VelocityTracker(速度跟踪器)实现抬起手指后的惯性滑动。
这样,根据上面的代码我们可以自己实现一个简单的ViewPager,效果如下:
自己手写一个ViewPager比看10遍代码还要顶用。上面实现的源码和sample已经上传github,项目会持续更新!
我的github:https://github.com/pop1234o/CustomViewApp
阅读全文
0 0
- 【Android API】3.ViewPager的实现原理和源码分析
- ConcurrentHashMap的实现原理和源码分析
- ConcurrentLinkedQueue的实现原理和源码分析
- ConcurrentLinkedQueue的实现原理和源码分析
- ViewPager实现源码分析
- Android --------------------ActionBar 与 ViewPager 和 ActionTab 切换 的源码实现
- Android:ViewPager动画的实现原理
- Android源码分析--Handler机制的实现与工作原理
- Android之ViewPager源码分析
- Android AsyncTask运作原理和源码分析
- Android AsyncTask运作原理和源码分析
- Android AsyncTask运作原理和源码分析
- Android AsyncTask运作原理和源码分析
- SwipeRefreshLayout和ViewPager滑动冲突的原理分析及解决方案
- Eoe客户端源码分析---ViewPager、 PageAdapter和PageIndicator 的使用
- promise实现原理的源码分析
- Android ListView实现不同item的方法和原理分析
- Android ListView实现不同item的方法和原理分析
- Java8集合及Stream操作
- java设计模式---抽象工厂模式
- 4.定义一个可以接收三个数字的函数,函数体内返回三个数字中最大的数字
- Iterator和ListIterator区别
- Java学习5:this关键字
- 【Android API】3.ViewPager的实现原理和源码分析
- Spring Boot整合集成StringRedisTemplate的简单记录
- JDBC连接数据库的开发流程
- 测试输入框常用特殊字符类别
- python django 环境搭建
- 动态代理
- 中山大学 简介
- iOS开发工具类,包含常用功能,为方便使用,特为常用功能封装并且使用宏定义方式运用
- 虚拟机中安装虚拟机助手 datatype.dtd cannot open no such file