viewflipper
平时我们在使用viewflipper的时候一方面感叹ViewFlipper的使用很简单,另一方面,我们时常感叹ViewFlipper给我们的接口方法太少,很多常用的效果都不好做,很难施展拳脚,这篇文章将详细介绍ViewFlipper的架构以及它的工作原理,相信看了这篇文章后你会发现ViewFlipper能展现的效果也可以很多,自己也可以根据自己的需求来定制属于自己的ViewFlipper。
类的继承关系图:
由类的关系图发现原来ViewFlipper是ViewAnimator的子类,而ViewAnimator又是Framelayout的子类。看到这个继承关系是否对ViewFlipper的工作原理有一定的猜想?
其实ViewFlipper工作机制很简单,如上图,就是将添加到ViewFlipper中的子View按照顺序定时的显示是其中一个子View,其他的子View设置为Gone状态。下面我们通过源码来详细解读这一过程。
ViewFlipper中的主要方法:
public void setFlipInterval(int milliseconds) {
mFlipInterval = milliseconds;
}
public void stopFlipping() {
mStarted = false;
updateRunning();
}
private void updateRunning() {
boolean running = mVisible && mStarted && mUserPresent;
if (running != mRunning) {
if (running) {
showOnly(mWhichChild);
message msg = mhandler.obtainMessage(FLIP_MSG);
mHandler.sendMessageDelayed(msg, mFlipInterval);
} else {
mHandler.removeMessages(FLIP_MSG);
}
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 Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == FLIP_MSG) {
if (mRunning) {
showNext();
msg = obtainMessage(FLIP_MSG);
sendMessageDelayed(msg, mFlipInterval);
}
}
}
};
如果是startFlipper,在mHandler中,将会处理这个message,也就是将下一个View的状态设置为Visible,其他的View设置为Gone状态。执行这一工作的方法为showNext()。此方法的实现在ViewAnimator。其实在ViewFlipper中,也就干了这么点事情。下面我们来看ViewAnimator。
ViewAnimator中的主要方法:
public void showNext() {
setdisplayedChild(mWhichChild + 1);
}
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);
}
}
这两个方法也就是计算出下一个View该显示哪个,确定了具体要显示的View后,就会调用showOnly(mWhichChild)方法。
void showOnly(int childIndex) {
final int count = getChildCount();
for (int i = 0; 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,能实现自动播放图片;2,手指可以左右滑动浏览图片;网上搜了有类似的例子,但是在手指滑动式图片不会跟着变化,而是在手指滑动后动画才开始(体验不好).
转载请说明出处:http://blog.csdn.net/ff20081528
更改时间:2014-1-13
基于ViewFlipper重写的图片浏览组件已经写好。博客地址: 基于ViewFlipper实现图片浏览
相关阅读
自定义viewFlipper的使用 viewFlipper是ViewAnimator的子类,而ViewAnimator又是继承自FrameLayout,而FrameLayout就是平时基本上只
什么是ViewFlipperViewFlipper,它是Android自带的一个多页面管理控件,可以实现引导页图片切换以及广告轮播的效果。其实ViewPager也
假设现在让你实现一个垂直循环滚动的效果,你的第一反应是什么?如果是立马想找第三方或者想着自定义(嘿!真不嫌麻烦),那么你对ViewFlip
本文转载自:http://blog.csdn.net/harvic880925/article/details/39585347 一、基本实现 ViewFlipper是一个切换控件,一般用于图片