平时我们在使用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工作机制的更多相关文章

  1. android 6.0 高通平台sensor 工作机制及流程(原创)

    最近工作上有碰到sensor的相关问题,正好分析下其流程作个笔记. 这个笔记分三个部分: sensor硬件和驱动的工作机制 sensor 上层app如何使用 从驱动到上层app这中间的流程是如何 Se ...

  2. Java IO工作机制分析

    Java的IO类都在java.io包下,这些类大致可分为以下4种: 基于字节操作的 I/O 接口:InputStream 和 OutputStream 基于字符操作的 I/O 接口:Writer 和 ...

  3. malloc 函数工作机制(转)

    malloc()工作机制 malloc函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表.调用malloc函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块.然后,将 ...

  4. springMVC工作机制和框架搭建配置说明

    先说一下springMVC的工作机制 1.springmvc把 所有的请求都提交给DispatcherServlet,它会委托应用系统的其他模块负责对请求进行真正的处理工作. 2.Dispatcher ...

  5. CKPT进程工作机制

    CKPT进程工作示意图 2.CKPT进程工作机制 检查点进程被触发的条件为: a> 当发生日志组切换时: b>  用户提交了事务时(commit): c>  Redo log buf ...

  6. 15 sql base line 工作机制

    <个人Configuration> 正常配置一下, 就OK了, 不用理了, oracle 11g 默认启动 发展: .从Oracle的发展角度来看,估计这种方法是Oracle发展和改进的方 ...

  7. HBase读写路径的工作机制

    出处:http://wuyudong.com/1946.html HBase 写路径工作机制 在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的.HBase 接到命令后存下变化信息, ...

  8. PHP自动加载__autoload的工作机制

    PHP自动加载__autoload的工作机制 PHP的懒加载lazy loading 在 2011年11月12日 那天写的     已经有 4559 次阅读了 感谢 参考或原文   服务器君一共花费了 ...

  9. hadoop MapReduce 工作机制

    摸索了将近一个月的hadoop , 在centos上配了一个伪分布式的环境,又折腾了一把hadoop eclipse plugin,最后终于实现了在windows上编写MapReduce程序,在cen ...

随机推荐

  1. HTML5——localStorage

    html5的学习,忘记的差不多了,特地拿出来重新记录一下,从它的本地存储开始吧! 假设这样的html结构: <div id= "one_storage" class=&quo ...

  2. css3 移动端 开关效果

    展示效果: 首先是html <div class="container"> <div class="bg_con"> <input ...

  3. Elastic Stack之kibana入门

    为了解决公司的项目在集群环境下查找日志不便的问题,我在做过简单调研后,选用Elastic公司的Elastic Stack产品作为我们的日志收集,存储,分析工具. Elastic Stack是ELK(E ...

  4. iOS 字符串 MD5

    iOS 字符串 MD5 Objective-C 实现 需要引入头文件 #import <CommonCrypto/CommonCrypto.h> 这里用方法实现 + (nullable N ...

  5. LABjs、RequireJS、SeaJS 哪个最好用?为什么?- 玉伯的回答

    LABjs 的核心是 LAB(Loading and Blocking):Loading 指异步并行加载,Blocking 是指同步等待执行.LABjs 通过优雅的语法(script 和 wait)实 ...

  6. 【Java学习笔记之二十三】instanceof运算符的用法小结

    instanceof运算符用法 运算符是双目运算符,左面的操作元是一个对象,右面是一个类.当左面的对象是右面的类创建的对象时,该运算符运算的结果是true,否则是false 说明: (1)一个类的实例 ...

  7. zoj 3494:BCD Code

    Description Binary-coded decimal (BCD) is an encoding for decimal numbers in which each digit is rep ...

  8. c语言基础学习08_内存管理

    =============================================================================涉及到的知识点有:一.内存管理.作用域.自动变 ...

  9. layui之事件监听(table)

    这几天在学习layui,感觉这框架挺好用的,前后端都适用,许多原本比较复杂的东西用该框架很容易就能实现. 今天看了table里的事件监听这个知识点. 语法:table.on('event(filter ...

  10. 浅谈event.client、event.screen与event.offset

    每每看到event.client.event.screen与event.offset这几个,头都大了,今天又碰到了,特来总结下. 1.event.screenX与event.screenY. 首先,e ...