了解ViewFlipper工作机制
平时我们在使用ViewFlipper的时候一方面感叹ViewFlipper的使用很简单,另一方面,我们时常感叹ViewFlipper给我们的接口方法太少,很多常用的效果都不好做,很难施展拳脚,这篇文章将详
细介绍ViewFlipper的架构以及它的工作原理,相信看了这篇文章后你会发现ViewFlipper能展现的效果也可以很多,自己也可以根据自己的需求来定制属于自己的ViewFlipper。
类的继承关系图:
由类的关系图发现原来ViewFlipper是ViewAnimator的子类,而ViewAnimator又是FrameLayout的子类。看到这个继承关系是否对ViewFlipper的工作原理有一定的猜想?
其实ViewFlipper工作机制很简单,如上图,就是将添加到ViewFlipper中的子View按照顺序定时的显示是其中一个子View,其他的子View设置为Gone状态。下面我们通过源码来详细解读这一过程。
ViewFlipper中的主要方法:
@android.view.RemotableViewMethod
public void setFlipInterval(int milliseconds) {
mFlipInterval = milliseconds;
} /**
* Start a timer to cycle through child views
*/
public void startFlipping() {
mStarted = true;
updateRunning();
} /**
* No more flips
*/
public void stopFlipping() {
mStarted = false;
updateRunning();
}
private void updateRunning(boolean flipNow) {
boolean running = mVisible && mStarted && mUserPresent;
if (running != mRunning) {
if (running) {
showOnly(mWhichChild, flipNow);
postDelayed(mFlipRunnable, mFlipInterval);
} else {
removeCallbacks(mFlipRunnable);
}
mRunning = running;
}
if (LOGD) {
Log.d(TAG, "updateRunning() mVisible=" + mVisible + ", mStarted=" + mStarted
+ ", mUserPresent=" + mUserPresent + ", mRunning=" + mRunning);
}
}
看这三个方法,我们就能知道不管是startFlipper还是stopFlipper方法,他们都是调用了updateRunning方法,不同的只是他们对于mStart这个变量设置的值不同,mStart值也就决定了ViewFlipper是start还是stop。
updateRunning方法它主要就是根据running值来判断是发送消息到消息栈中,还是移除消息。
private final Runnable mFlipRunnable = new Runnable() {
@Override
public void run() {
if (mRunning) {
showNext();
postDelayed(mFlipRunnable, mFlipInterval);
}
}
};
如果是startFlipper,,也就是将下一个View的状态设置为Visible,其他的View设置为Gone状态。执行这一工作的方法为showNext()。此方法的实现在ViewAnimator。其实在ViewFlipper中,也就干了这么点事情。下面我们来看ViewAnimator。
ViewAnimator中的主要方法:
public void showNext() {
setDisplayedChild(mWhichChild + );
}
public void setDisplayedChild(int whichChild) {
mWhichChild = whichChild;
if (whichChild >= getChildCount()) {
mWhichChild = ;
} else if (whichChild < ) {
mWhichChild = getChildCount() - ;
}
boolean hasFocus = getFocusedChild() != null;
// This will clear old focus if we had it
showOnly(mWhichChild);
if (hasFocus) {
// Try to retake focus if we had it
requestFocus(FOCUS_FORWARD);
}
}
这两个方法也就是计算出下一个View该显示哪个,确定了具体要显示的View后,就会调用showOnly(mWhichChild)方法
void showOnly(int childIndex) {
final int count = getChildCount();
for (int i = ; i < count; i++) {
final View child = getChildAt(i);
final boolean checkForFirst = (!mFirstTime || mAnimateFirstTime);
if (i == childIndex) {
if (checkForFirst && mInAnimation != null) {
child.startAnimation(mInAnimation);
}
child.setVisibility(View.VISIBLE);
mFirstTime = false;
} else {
if (checkForFirst && mOutAnimation != null && child.getVisibility() == View.VISIBLE) {
child.startAnimation(mOutAnimation);
} else if (child.getAnimation() == mInAnimation)
child.clearAnimation();
child.setVisibility(View.GONE);
}
}
}
这个方法主要的工作就是显示mWhichChild,将其他的设置为Gone状态。同时在这个方法中还会进行切换动画的调用,如果有动画的话。
其实在ViewAnimator类中,主要就是干了两件事,一件就是按照要求将需要显示的子view设置为Visible状态,其他的子View设置为Gone状态。另外一件就是动画的处理工作。
看完这个有没有发现其实ViewFlipper是这样的简单?
了解ViewFlipper工作机制的更多相关文章
- android 6.0 高通平台sensor 工作机制及流程(原创)
最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...
- Java IO工作机制分析
Java的IO类都在java.io包下,这些类大致可分为以下4种: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...
- malloc 函数工作机制(转)
malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...
- springMVC工作机制和框架搭建配置说明
先说一下springMVC的工作机制 1.springmvc把 所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作. 2.Dispatcher ...
- CKPT进程工作机制
CKPT进程工作示意图 2.CKPT进程工作机制 检查点进程被触发的条件为: a> 当发生日志组切换时: b> 用户提交了事务时(commit): c> Redo log buf ...
- 15 sql base line 工作机制
<个人Configuration> 正常配置一下, 就OK了, 不用理了, oracle 11g 默认启动 发展: .从Oracle的发展角度来看,估计这种方法是Oracle发展和改进的方 ...
- HBase读写路径的工作机制
出处:http://wuyudong.com/1946.html HBase 写路径工作机制 在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的.HBase 接到命令后存下变化信息, ...
- PHP自动加载__autoload的工作机制
PHP自动加载__autoload的工作机制 PHP的懒加载lazy loading 在 2011年11月12日 那天写的 已经有 4559 次阅读了 感谢 参考或原文 服务器君一共花费了 ...
- hadoop MapReduce 工作机制
摸索了将近一个月的hadoop , 在centos上配了一个伪分布式的环境,又折腾了一把hadoop eclipse plugin,最后终于实现了在windows上编写MapReduce程序,在cen ...
随机推荐
- 通过Chocolatey软件包管理器安装.NET Core
在Linux的世界里,有了yum/apt-get百分之九十的软件都可以通过它来安装管理.但是在Windows系统上,装个软件还是挺折腾的.比如我要装个Chrome浏览器,我先得打开IE浏览器吧,我还打 ...
- 解读Scrum燃尽图
我的Understand the burndown chart读书笔记. 什么是燃尽图: 在敏捷开发中,燃尽图主要用于显示某一特定时间段内团队的剩余工作量,从而了解团队状态和项目进度. 燃尽图其实很简 ...
- 【转载】Linux cgroup资源隔离各个击破之 - io隔离
Linux Cgroup blkio子系统的用法. blkio子系统支持的两种IO隔离策略 .1. (Completely Fair Queuing 完全公平队列)cfq io调度策略,支持按权重 ...
- 如何在一个项目中同时包含mvc建站、webapi接口
项目做得多了..就会发现有些小项目不想建太多的项目..现在思明在这里和大家分享一下如果再一个项目中同时包含mvc建站以及实现webapi接口 1.新建项目 aps.net web 应用程序 2 新建模 ...
- windows第七层负载均衡--基于IIS的ARR负载均衡
载均衡有很多种方法,有硬件负载均衡,软件负载均衡,还可以从域名解析下手. 不过,今天只讲软件负载均衡 软件负载均衡一般分两种,从网络协议来讲(tcp/ip),主要集中在第四层和第七层进行负载均衡. 第 ...
- python 浅析IO 模型
协程:遇到IO操作就切换,但是什么时候切回去呢?怎么确定IO操作? 很多程序员可能会考虑使用"线程池"或"连接池"."线程池"旨在减少创建和 ...
- $(document).ready()和window.onload之间的差异
最近使用$(document).ready(function(){})遇到一个问题:加载页面后发送数据请求后台,得到的数据不对,后发现请求后台时,发送的数据为空,没有获取到值导致的.------改成w ...
- 下载的js文件本地编辑器打开中文乱码如何解决
今天遇到的小问题,已解决,直接上图 下载直接打开是这样的 用记事本打开 另存为utf-8格式 正常了!
- 如何调用sklearn模块做交叉验证
终于搞明白了如何用sklearn做交叉验证!!! 一般在建立完模型之后,我们要预测模型的好坏,为了试验的可靠性(排除一次测试的偶然性)我们要进行多次测试验证,这时就要用交叉验证. sklearn中的s ...
- 学习笔记-nodejs报错
端口被占用 解决办法:打开控制管理器关掉node.exe进程 如果找不到可以使用命令行:netstat -ano | findstr 8000 找到进程的pid,然后到控制管理器找到进程杀掉. net ...