平时我们在使用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. NPOI json转Excel DataTable转Excel ,Excel转DataTable

    JsonToExcel: public static void JsonToExcel(List<Dictionary<string, object>> json, strin ...

  2. Webpack+vue2.0如何注册全局组件 (01)

    Part 1, 问题: webpack + vue2.0框架中,如何在入口js中注册组件? 就是在一个月以前,匆匆闯入vuejs这个社群,基本了解了vuejs的一些基础特性和语法.笔者兴致勃勃地开始想 ...

  3. python中的slice用法

    同事在网上做题碰到的 >>> items = [0,1,2,3,4,5,6,7,8,9] >>> a = _____(2,4) >>> items ...

  4. 11、ABPZero系列教程之拼多多卖家工具 拼团提醒功能页面实现

    上一篇讲解了拼团提醒逻辑功能实现,现在继续实现页面功能. Core项目 打开AbpZeroTemplate-zh-CN.xml语言文件,在末尾添加如下代码: 文件路径:D:\abp version\a ...

  5. 初识mysql学习笔记

    使用VMVirtualBox导入Ubuntu后,可以通过sudo apt-get install mysql-server命令下载mysql. 在学习过程中,我遇到了连接不上Xshell的问题.最终在 ...

  6. Object.prototype.toString.call()方法浅谈

    使用Object.prototype上的原生toString()方法判断数据类型,使用方法如下: Object.prototype.toString.call(value) 1.判断基本类型: Obj ...

  7. CTF---Web入门第一题 what a fuck!这是什么鬼东西?

    what a fuck!这是什么鬼东西?分值:10 来源: DUTCTF 难度:易 参与人数:7942人 Get Flag:3358人 答题人数:3475人 解题通过率:97% what a fuck ...

  8. 51 Nod 1007 正整数分组【类01背包】

    1007 正整数分组 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 将一堆正整数分为2组,要求2组的和相差最小. 例如:1 2 3 4 5,将1 2 4分为1组, ...

  9. Open Judge 2750 鸡兔同笼

    2750:鸡兔同笼                                                                                            ...

  10. POJ 1655 Balancing Act【树的重心】

    Balancing Act Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14251   Accepted: 6027 De ...