ViewFlipper原理

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行,所以实现原理和一些代码细节分析起来都不难,所以感兴趣的大家可以自行看一下

你可能感兴趣的:(ViewFlipper原理)