ViewFlipper简单学习笔记
2015-12-15 19:59
399 查看
相信各位android程序猿对ViewFlipper这个组件并不陌生,它的的主要作用就是用来切换View的时候提供页面间的动画效果,这点从其父类的功能以及其父类的名字可以看出来:
它的父类的名字为ViewAnimator,其直接父类为ViewGroup,包含了两个动画的引用:
moutAnimation:这个Animation是用于将当前页面的View退出时的动画
上面的伪代码可以很清晰的说明了ViewAnimator或者ViewFlipper的页面切换动画的实现原理,当然还不是很完善,随着博文的进行会逐一完善上面的伪代码。
因为ViewAnimator继承自ViewGroup,所以可以调用ViewGroup的addView几个相关的重载方法进行View的添加,这些添加进来的各个View按照添加的顺序添加到了ViewGroup的mChildren数组里面,ViewFlipper或者ViewAnimator切换View的时候就是切换的里面的这些被添加进来的View.当然ViewAnimator也重写了其父类的ViewGroup的一个AddView方法:
上面的代码很明显,如果整个页面就一页的话就直接显示,如果连续调用该方法的话,会将第一页的View显示,而其余页的View都会隐藏。当然我们可以直接调用ViewGroup的系列addView方法来完成相关功能。既然第一个页面为View.VISIABLE其余的页面的View为GONE,那么很容易猜出来实现页面的切换的核心逻辑的为:
1)隐藏当前页的View,即将当前的View可见性设置为GONE
2)显示即将切换进来的View(上一页或者下一页的View) ,设置为Visiable
如果添加上动画效果的话,结合上问所说的伪代码,可以讲上面伪代码进步完善:
实现上一页或者下一页的切换ViewFlipper的父类ViewAnimator提供了两个方法:
1)showNext:显示下一页的View。
2)showPrevious显示上一页的View。
其实继续追踪它的实现源码,正如上面的额伪代码所说的描述的那样,可以发现其原理也很简单:因为把每一页的View都加入到了一个数组里面,所以需要根据当前数组下标来获取上一页和下一页的View,这样的ViewFlipper或者ViewAnimator的原理就如下:
在ViewAnimator中提供了showNext()和showPrevious() 方法来切换下一页和上一页,追踪下源代码可以发现他们只是调用了setDisplayedChild方法:
通过什么的方法可以得出这个一个结论:当一直调用showNext()显示下一页的时候,如果此时已经处于最后一页再调用showNext()方法的话,那么就会显示第一页的View;如果已经处于第一页再次调用showPrevious()的话,会显示最后一页的View。其实根据setDisplayedChild这个方法可以实现跳页的效果,比如在TV端用户操控遥控器输入数字键,让ViewFlipper跳到制定的页数这样的功能。最终实现View的切换逻辑是在showOnly里面,这个方法原理正如上面的伪代码一样,很容易看明白:
其实通过上面对ViewAnimator的讲解,完全可以通过ViewAnimator这个类而不用其子类ViewFilpper来实现类似PPT的功能或者页面轮播功能,核心原理也很简单:用定时器或者延迟消息,每隔一段时间调用showNext()方法并添加自定义Animation即可,其伪代码如下:
这个类似ppt页面切换的demo源代码点此(,源代码很简单,当然按照屌丝程序员惯例,图片都是从网上搜的美女图
)
如果按照上面所说的话ViewAnimator这个类就可以实现基本的页面切换的功能了,那么它的子类ViewFilpper又对ViewAnimator做了什么扩展呢?其实它做的功能的拓展也很简单,总的来说就是提供了startFlipping()和stopFlipping()方法,一直调用startFlipping()的话也可以实现类似ppt的效果,其核心原理也是发送延迟消息,并不断调用其父类ViewAnimator的showNext()方法,只不过用户可以调用 setFlipInterval(int milliseconds)方法来设置页面切换的速度,具有可控性。具体的源代码就不贴出来了,核心原理跟上面所说的demo里面的很类似。并可以调用isFlipping方法来判断ViewFlipper是否在进行页面的轮播或者切换
同时ViewFlipper还定义了一个广播来监听屏幕是否关闭和打开,来控制是否轮播。
到文章的最后,需要说一情况:在qq群里面有讨论技术的时候有些人总有一种误区就是自定义View一定要重写onMeasure或者onLayout方法,其实 这个打破这个误区也很简单,比如这个viewAnimator和ViewFlipper仅仅只是用了ViewGroup的addView的功能,在加上动画效果。他们并没有重写View的onMeasure或者onLayout方法,自定义view根据具体的需求来完成的,当然有的简单有的复杂,比如特殊的动画效果,扩展TextView来实现滚动的手动暂停和开始等,自定义view在这里因为本人技术有限就不多说了
它的父类的名字为ViewAnimator,其直接父类为ViewGroup,包含了两个动画的引用:
Animation mInAnimation; Animation mOutAnimation;mInAnimation:这个Animation是用于将上一页或者下一页的View切换进来时的动画
moutAnimation:这个Animation是用于将当前页面的View退出时的动画
if(switchView){ //让当前显示的View执行退出动画 currentView.startAnimation(mOutAnimation); //让即将要显示的View执行进入动画 nextView_or_preView.startAnimatioin(mInAnimation); }
上面的伪代码可以很清晰的说明了ViewAnimator或者ViewFlipper的页面切换动画的实现原理,当然还不是很完善,随着博文的进行会逐一完善上面的伪代码。
因为ViewAnimator继承自ViewGroup,所以可以调用ViewGroup的addView几个相关的重载方法进行View的添加,这些添加进来的各个View按照添加的顺序添加到了ViewGroup的mChildren数组里面,ViewFlipper或者ViewAnimator切换View的时候就是切换的里面的这些被添加进来的View.当然ViewAnimator也重写了其父类的ViewGroup的一个AddView方法:
/** *@param child View要添加到ViewFlipper或者ViewAnimator中的View */ @Override public void addView(View child, int index, ViewGroup.LayoutParams params) { super.addView(child, index, params); //如果只添加进来一个View,就直接显示 if (getChildCount() == 1) { child.setVisibility(View.VISIBLE); } else {// child.setVisibility(View.GONE); } }
上面的代码很明显,如果整个页面就一页的话就直接显示,如果连续调用该方法的话,会将第一页的View显示,而其余页的View都会隐藏。当然我们可以直接调用ViewGroup的系列addView方法来完成相关功能。既然第一个页面为View.VISIABLE其余的页面的View为GONE,那么很容易猜出来实现页面的切换的核心逻辑的为:
1)隐藏当前页的View,即将当前的View可见性设置为GONE
2)显示即将切换进来的View(上一页或者下一页的View) ,设置为Visiable
如果添加上动画效果的话,结合上问所说的伪代码,可以讲上面伪代码进步完善:
if(switchView){ //让当前显示的View执行退出动画 currentView.startAnimation(mOutAnimation); //隐藏 currentView.setVisibility(View.GONE); //让即将要显示的View执行进入动画 nextView_or_preView.startAnimatioin(mInAnimation); //显示View nextView_or_preView.setVisibility(View.VISIBLE); }
实现上一页或者下一页的切换ViewFlipper的父类ViewAnimator提供了两个方法:
1)showNext:显示下一页的View。
2)showPrevious显示上一页的View。
其实继续追踪它的实现源码,正如上面的额伪代码所说的描述的那样,可以发现其原理也很简单:因为把每一页的View都加入到了一个数组里面,所以需要根据当前数组下标来获取上一页和下一页的View,这样的ViewFlipper或者ViewAnimator的原理就如下:
//切换view void switchView(int index){ for(int i=0;i<childrenCount;i++){ View child = mViews[i]; if(index=i){ child.startAnimation(mInAnimation); child.setVisiablity(View.VISIABLE); }else{ child.startAnimation(mOutAnimation); child.setVisiablity(View.GONE); } } }
在ViewAnimator中提供了showNext()和showPrevious() 方法来切换下一页和上一页,追踪下源代码可以发现他们只是调用了setDisplayedChild方法:
/** *@param whichChild 要显示的View在viewGroup数组中的索引 */ public void setDisplayedChild(int whichChild) { mWhichChild = whichChild; //通过这个可以发现, if (whichChild >= getChildCount()) { mWhichChild = 0; } else if (whichChild < 0) { mWhichChild = getChildCount() - 1; } 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); } }
通过什么的方法可以得出这个一个结论:当一直调用showNext()显示下一页的时候,如果此时已经处于最后一页再调用showNext()方法的话,那么就会显示第一页的View;如果已经处于第一页再次调用showPrevious()的话,会显示最后一页的View。其实根据setDisplayedChild这个方法可以实现跳页的效果,比如在TV端用户操控遥控器输入数字键,让ViewFlipper跳到制定的页数这样的功能。最终实现View的切换逻辑是在showOnly里面,这个方法原理正如上面的伪代码一样,很容易看明白:
void showOnly(int childIndex, boolean animate) { final int count = getChildCount(); //对View进行遍历 for (int i = 0; i < count; i++) { final View child = getChildAt(i); if (i == childIndex) {//即将显示的View if (animate && mInAnimation != null) {//执行显示动画 child.startAnimation(mInAnimation); } //设置可见 child.setVisibility(View.VISIBLE); mFirstTime = false; } else {//关闭其他的且可见的View if (animate && mOutAnimation != null && child.getVisibility() == View.VISIBLE) { child.startAnimation(mOutAnimation);//执行动画 } else if (child.getAnimation() == mInAnimation) child.clearAnimation(); //设置不可见 child.setVisibility(View.GONE); } } }
其实通过上面对ViewAnimator的讲解,完全可以通过ViewAnimator这个类而不用其子类ViewFilpper来实现类似PPT的功能或者页面轮播功能,核心原理也很简单:用定时器或者延迟消息,每隔一段时间调用showNext()方法并添加自定义Animation即可,其伪代码如下:
showPPT(){ sendMsgDelayed(msg,delayed_time); } handleMsg(){ viewAnimator.showNext(); sendMsgDelayed(msg,delayed_time); }
这个类似ppt页面切换的demo源代码点此(,源代码很简单,当然按照屌丝程序员惯例,图片都是从网上搜的美女图
)
如果按照上面所说的话ViewAnimator这个类就可以实现基本的页面切换的功能了,那么它的子类ViewFilpper又对ViewAnimator做了什么扩展呢?其实它做的功能的拓展也很简单,总的来说就是提供了startFlipping()和stopFlipping()方法,一直调用startFlipping()的话也可以实现类似ppt的效果,其核心原理也是发送延迟消息,并不断调用其父类ViewAnimator的showNext()方法,只不过用户可以调用 setFlipInterval(int milliseconds)方法来设置页面切换的速度,具有可控性。具体的源代码就不贴出来了,核心原理跟上面所说的demo里面的很类似。并可以调用isFlipping方法来判断ViewFlipper是否在进行页面的轮播或者切换
同时ViewFlipper还定义了一个广播来监听屏幕是否关闭和打开,来控制是否轮播。
到文章的最后,需要说一情况:在qq群里面有讨论技术的时候有些人总有一种误区就是自定义View一定要重写onMeasure或者onLayout方法,其实 这个打破这个误区也很简单,比如这个viewAnimator和ViewFlipper仅仅只是用了ViewGroup的addView的功能,在加上动画效果。他们并没有重写View的onMeasure或者onLayout方法,自定义view根据具体的需求来完成的,当然有的简单有的复杂,比如特殊的动画效果,扩展TextView来实现滚动的手动暂停和开始等,自定义view在这里因为本人技术有限就不多说了
相关文章推荐
- hdoj1280前m大的数
- Java设计模式之策略模式
- UCOSIII 任务管理(中)
- 缓存算法(页面置换算法)-FIFO、LFU、LRU
- 第十周项目3 利用二叉树遍历思想解决问题
- 《spring技术内幕》学习(二)ioc容器实现
- cocos2d-x从c++文件生成lua绑定文件及lua脚本文件
- spring-session源码解读-5
- 将汉字转化为拼音
- 求右边区间的最大值
- Spring AOP实现方式
- hdoj1877又一版 A+B
- JAVA设计模式之抽象工厂模式
- java设计模式之建造者模式
- IOS的MVC
- pclint在VS2013中的配置
- Mac OS X下的动态链接库
- 23种设计模式汇总整理
- [转]如何管理一个远程团队
- Java中堆内存和栈内存详解