ViewFlipper
是一个上下轮播的组件,只不过没有viewpager那么有名
ViewFlipper工作原理
ViewFlipper的工作原理和源码都很简单,代码量不多
首先ViewFlipper的父类是ViewAnimator,ViewAnimator的父类是FrameLayout
既然是framelayout那么大家有没有想到什么,其实轮播就是对当前的子view进行显示visible,对其它的子view进行隐藏gone
核心方法
void showOnly(int childIndex, boolean animate) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
//遍历取出所有子控件
final View child = getChildAt(i);
//与参数索引进行比较
if (i == childIndex) {
//如果用户设置的动画就先播放动画
if (animate && mInAnimation != null) {
child.startAnimation(mInAnimation);
}
child.setVisibility(View.VISIBLE);
mFirstTime = false;
} else {
if (animate && mOutAnimation != null && child.getVisibility() == View.VISIBLE) {
child.startAnimation(mOutAnimation);
} else if (child.getAnimation() == mInAnimation)
// 这里是一个思考点,google为什么要clearAnimation?因为有时
// 不clear掉动画会影响View.GONE的执行,所以很多涉及到动画
// 后隐藏控件的需求,都可以参考一下
child.clearAnimation();
child.setVisibility(View.GONE);
}
}
}
轮播其实就是postDelayed而showNext方法依次调用setDisplayedChild(mWhichChild + 1);mWhichChild就是当前显示view的索引,而setDisplayedChild中又调用了showOnly(mWhichChild);
private final Runnable mFlipRunnable = new Runnable() {
@Override
public void run() {
if (mRunning) {
showNext();
postDelayed(mFlipRunnable, mFlipInterval);
}
}
};
动画的展示是
setDisplayedChild是ViewAnimator的方法,setDisplayedChild中调用了 showOnly(mWhichChild);该方法内部mInAnimation,mOutAnimation执行的动画移入移出
void showOnly(int childIndex, boolean animate) {
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (i == childIndex) {
if (animate && mInAnimation != null) {
child.startAnimation(mInAnimation);
}
child.setVisibility(View.VISIBLE);
mFirstTime = false;
} else {
if (animate && mOutAnimation != null && child.getVisibility() == View.VISIBLE) {
child.startAnimation(mOutAnimation);
} else if (child.getAnimation() == mInAnimation)
child.clearAnimation();
child.setVisibility(View.GONE);
}
}
}
ViewFlipper 和 ViewAnimator 源码加在一起只有500行,所以实现原理和一些代码细节分析起来都不难,所以感兴趣的大家可以自行看一下