ViewFlipper简单学习笔记
来源:互联网 发布:手机mac地址怎么改 编辑:程序博客网 时间:2024/06/10 22:34
它的父类的名字为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的原理就如下:
//切换viewvoid 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在这里因为本人技术有限就不多说了
- ViewFlipper简单学习笔记
- Android学习笔记————简单认识ViewFlipper
- Android学习笔记之ViewFlipper
- Android学习笔记之ViewFlipper
- android widget——ViewFlipper 学习笔记
- Android-ViewFlipper子界面自动轮播-学习笔记
- Android学习笔记二十二之ViewFlipper&&AdapterViewFlipper
- Android学习笔记二十二之ViewFlipper&&AdapterViewFlipper
- ViewFlipper的简单使用
- ViewFlipper的简单使用
- Android ViewFlipper 简单应用
- android笔记12-viewFlipper
- Android学习之ViewFlipper
- Android学习之ViewFlipper
- ViewFlipper的学习
- ViewFlipper 简单封装与使用
- 学习笔记之——使用ViewFlipper实现竖直滚动广告
- ViewFlipper
- centos7 mysql-server 安装
- java多态的理解
- bootstrap按钮组(二)
- servlet以及spring mvc实现bigpipe技术分享
- 【LeetCode】6 ZigZag Conversion
- ViewFlipper简单学习笔记
- mongoDB备份恢复数据库
- IOS id用法
- 武汉大学2013linux大作业
- STM32的LED灯实验
- 练习打字
- 装修那些事儿
- memcache安装
- 网站框架选择