android滑屏两三事
一个滑屏Demo,所包含的知识点:
Android相关:
How to create a ViewGroup
Usage of Scroller
OnTouchEvent & onInterceptTouchEvent
Android无关:
判断是否换页
判断下页是否有效
细节问题(滑屏实现)
How to create a ViewGroup
一般要重载两个函数,而且是必须的:
onMeasure:超类的该方法,只会计算该View本身的默认大小,并不会计算其child的大小,如果不重载该方法,子类大小全为0,不会显示出来。
一般的方法为:for(i=0; i<getChildCount(); i++)
getChildAt(i).measure();
onLayout:该方法为抽象方法,说明ViewGroup并没有默认规定子视图的排列方式,必须其子类来定义其子视图在父视图里面的排列方式。
正确的重载了这两个方法,就可以正确的显示一个ViewGroup了。
Additional:
ViewGroup默认是不会回调onDraw()的。因为ViewGroup是个子视图的容器,本身并没有什么好画的,所以默认它是willNotDraw(),即它是不会执行draw命令的,也就不会回调onDraw函数。如果ViewGroup有背景色,即setBackground后,那么他将会执行onDraw回调。
Usage of Scroller
Scroller是个Helper类,仅仅是为了方便实现滑屏,没有这个类,照样可以实现滑屏,只是滑屏每个时刻的参数需要自己实现。
Scroller有两个重要方法:startScroll和computeScrollOffset
startScroll乍一看貌似掉了这个函数就能实现View的滑屏了,但是仔细想想,这个类的构造函数或者startScroll方法都没有传入要滑动的View,那Scroller怎么知道要滑哪个View呢。于是一开始我直接在ViewGroup内部构造了一个Scroller,然后startScroll->invalidate(),然后Nothing happens。之后看了Scroller代码实现后,才发现Scroller只是帮你实现了View从A点到B点滑动过程中所有的XY坐标。startScroll表示开始计算坐标,然后用computeScrollOffset获取计算出的坐标,在滑屏动画过程中,随着时间的流逝,每次获得的坐标不同,这一连串坐标连起来,便形成了动画,那么何时调用computeScrollOffset获取坐标呢?android View架构中已经对滑屏进行了支持,每次draw的过程中都会回调computeScroll。computeScroll回调用来通知View更新自己的滑屏偏移位置,即mScrollX,mScrollY。默认是回调为空,即对偏移位置不做调整。接下来对mScrollX,mScrollY进行简单介绍,android View架构本身支持View的滑动,于是有了mScrollX,mScrollY这两个变量,使用ScrollTo和ScrollBy方法对View进行滑动,默认mScrollX,mScrollY为0,表示在draw的时候,该View不进行任何偏移。该在哪就在哪。如果使用了ScrollBy和ScrollTo那么mScrollX,mScrollY将会发生改变,在下一次draw的时候该View就会进行相应偏移。ScrollBy和ScrollTo不会产生动画,即时生效,简而言之方法只要执行两个操作,对mScrollX,mScrollY进行赋值,调用invaildate()。
于是事件驱动发生滑屏动画实现大致为这样
//某事件触发该方法
Void Scroll(){
//横向滑动,startX为起始位置,dx为偏移量,1000表示整个过程耗时1000毫秒
mScroller.startScroll(startX,0, dx, 0,1000);
//触发重绘
invalidate();
}
//View的回调
Void computeScroll(){
如果if返回true表示动画还没结束,获取偏移量
if(mScroller.computeScrollOffset()){
scrollTo(mScroller.getCurrX(),mScroller.getCurrY());
invalidate();
}
对invalidate的一些说明,invalidate是个异步调用过程,即调用invalidate不会立即进行重绘,它只是发送一个重绘请求,所以在onDraw里面调用invalidate不会造成onDraw的无限递归调用.只是会在UI线程的消息池里面不断产生重绘请求,不断产生重绘请求+每次View的属性参数不同,就造成了动画效果
OnTouchEvent & onInterceptTouchEvent
要进行手势滑屏,那么就必须重载OnTouchEvent,在按下的时候记录位置,更新状态,在Move的时候,ScrollBy与上次距离的偏移量。在Up的时候,判断是否换页,然后就走startScroll的流程
onInterceptTouchEvent对于一个最基本的手势滑屏应该说是不必要的,重载该方法的主要意义在于:当手指按在其子视图上面时截获其触屏消息,并转发到父视图的OnTouchEvent。但是对于完整的手势滑屏应该说是不可或缺的,因为你不能让用户点在空白区域时可以滑动,而点在子视图上面却无法滑动,特别是当父视图的子视图相当多时(如桌面),onInterceptTouchEvent就显得相当必要了。
判断是否换页
目前有两种算法:一种是根据按下去的位置和手指离开屏幕位置的差值来决定是否可以换页,另外一种是更主流的使用速度追踪器(VelocityTracker)来根据滑动时的速度和距离来判断。相对来说,第二种算法会有更好的用户体验。而第一种方法更加基本,对于描述滑屏更加容易理解。
判断下页是否有效
这个非常简单,每一个子视图都是一个Page,所以当要滑过去的那个视图,不在父视图的子节点范围内,就是个无效页
private boolean isVaildScreen(int which){
intcount = getChildCount();
if(which> count-1 || which < 0){
returnfalse;
}
returntrue;
}
细节问题(滑屏实现)
完成了android相关的三个技术点之后,基本就可以搭出手势滑屏的基本雏形。但是这只是个半成品。在细节方面还有很多地方需要完善的:
比如在每次动画滑屏前都需要进行前一次动画的取消。
if(!mScroller.isFinished()){
mScroller.abortAnimation();
}
在onTouchEvent的Move事件:需要避免微距的滑动,因为这样会让界面看上去会发飘一样。可以增加这次坐标和上次坐标的差值比较,如果大于一个阀值那么才进行滑动
If(Math.abs(x-mLastX) >ViewConfiguration.getTouchSlop())
还有一个关键点,就是手势滑和动画滑的配合,计算startX和dx
android滑屏两三事相关推荐
- android 滑屏功能,Android 滑屏效果实现方式汇总
Android的滑屏,最近在研究这个东西,发现新浪微博的客户端.腾讯微博的客户端都有这个功能.目前到今天为止,腾讯和微博的客户端都是使用viewPager控件写的,可能重写了一些地方.而腾讯老版本的q ...
- android滑屏效果,Android使用ViewFlipper和GestrueDetector共同实现滑屏效果实例
本文实例讲述了Android使用ViewFlipper和GestrueDetector共同实现滑屏效果.分享给大家供大家参考,具体如下: 关于GestureDetector的相关知识,前面已经介绍过了 ...
- android滑屏设计规范,Android使用ViewFlipper和GestrueDetector共同实现滑屏效果实例
本文实例讲述了Android使用ViewFlipper和GestrueDetector共同实现滑屏效果.分享给大家供大家参考,具体如下: 关于GestureDetector的相关知识,前面已经介绍过了 ...
- Android滑屏速度,让安卓手机流畅度瞬间飙升60%,这个小技巧厉害了
原标题:让安卓手机流畅度瞬间飙升60%,这个小技巧厉害了 6月份各大国产手机品牌相继推出自己的旗舰机,华为小米等厂商都推出自己的旗舰机,就连最近几年一直主打中端手机的ov厂商也推出了顶级旗舰机,vov ...
- Android滑屏 mScrollX mScrollY scrollTo() scrollBy()
首先 ,我们必须明白在Android View视图是没有边界的,Canvas是没有边界的,只不过我们通过绘制特定的View时对 Canvas对象进行了一定的操作,例如 : translate(平移). ...
- android滑屏设计规范,安卓设计如何实现滑动屏幕出现如图的效果
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.util.ArrayList; import android.content.Context; import android.gr ...
- android滑屏的设计思路,安卓设计如何实现滑动屏幕出现如图的效果
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.util.ArrayList; import android.content.Context; import android.gr ...
- android滑屏轨迹运动,Android Animation实现元素在屏幕上按照指定轨迹运动,以及出现NullPointerException的解决方案...
因项目需要,在Android中实现了一个动画,当在Activity中点击特定按钮时,会在屏幕上添加一个ImageView,并按照指定的起点.终点,沿着特定的轨迹运动(例如直线). 实现方法 实现思路是 ...
- 手机桌面左右滑屏不成功问题log分析
问题背景 滑动测试,单手握持测试机,大拇指在测试机桌面做左右滑屏操作,偶现滑屏不成功. 问题分析步骤 (1)首先根据"视频"或者"log中关于问题现象的关键log&quo ...
最新文章
- was unable to refresh its cache! status = Cannot execute request on any known server
- .NetCore Winform控制台 做HTTP Host,简易接口
- C++知识点41——运算符的重载概念与分数类实现(下)
- java 代码运行速度慢_C代码的运行速度总是比Java快,对吧? 错误!
- 谁说发 paper 一定要追快打新?2021年,研究 word2vec 也能中顶会!
- 百度SEO站群裕网云综合导航网html源码
- CVPR 2019 | 旷视提出新型目标检测损失函数:定位更精准
- 机器学习焦点,范德比尔特(Vanderbilt U)的医疗机器人以及更多开源新闻
- retrofit与rxjava使用
- h5+vue+php仿微信源码-泡泡IM
- VS使用教程(使用visual studio编写C语言程序),编写c的入门教程
- UnityC# MD5验证
- linux运行ktr文件,Linux下用命令來執行kettle文件資源庫的文件ktr與kjb的方法
- PAT(甲)1124 Raffle for Weibo Followers——未完成
- Ubuntu发烧友三部曲
- DHCP和域的概念知识
- MySQL中出现Duplicate entry 'XXX' for key 'PRIMARY'解决方案
- python计算线段夹角
- 读《白鹿原》有感其二之乡约小谈
- 关于图灵测试和中文屋Chinese room的理解
热门文章
- linux part用法,linux中sfdisk及parted的用法
- qt版——操作系统课程设计(含可视化界面)
- 如何迅速有效学习web前端开发?
- java替换图片内容
- MATLAB代码:基于主从博弈理论的共享储能与综合能源微网优化运行研究
- createnewfile() java_Java File createNewFile()方法
- 三维重建(二):包裹相位以及绝对相位求解
- 北京之旅--国家图书馆
- 杨冬敏老师:老板懂点财务知识,看懂三张报表
- Microsoft Project的RibbonXml VBA项目中不能使用带参数的过程