zoukankan      html  css  js  c++  java
  • 了解ViewFlipper工作机制

    平时我们在使用ViewFlipper的时候一方面感叹ViewFlipper的使用很简单,另一方面,我们时常感叹ViewFlipper给我们的接口方法太少,很多常用的效果都不好做,很难施展拳脚,这篇文章将详
    细介绍ViewFlipper的架构以及它的工作原理,相信看了这篇文章后你会发现ViewFlipper能展现的效果也可以很多,自己也可以根据自己的需求来定制属于自己的ViewFlipper。
    类的继承关系图:

    由类的关系图发现原来ViewFlipper是ViewAnimator的子类,而ViewAnimator又是FrameLayout的子类。看到这个继承关系是否对ViewFlipper的工作原理有一定的猜想?

    其实ViewFlipper工作机制很简单,如上图,就是将添加到ViewFlipper中的子View按照顺序定时的显示是其中一个子View,其他的子View设置为Gone状态。下面我们通过源码来详细解读这一过程。

    ViewFlipper中的主要方法:

    @android.view.RemotableViewMethod
    public void setFlipInterval(int milliseconds) {
        mFlipInterval = milliseconds;
    }
    
    /**
    * Start a timer to cycle through child views
    */
    public void startFlipping() {
        mStarted = true;
        updateRunning();
    }
    
    /**
    * No more flips
    */
    public void stopFlipping() {
        mStarted = false;
        updateRunning();
    }
    private void updateRunning(boolean flipNow) {
        boolean running = mVisible && mStarted && mUserPresent;
        if (running != mRunning) {
            if (running) {
                showOnly(mWhichChild, flipNow);
                postDelayed(mFlipRunnable, mFlipInterval);
            } else {
                removeCallbacks(mFlipRunnable);
            }
            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 Runnable mFlipRunnable = new Runnable() {
        @Override
        public void run() {
            if (mRunning) {
                showNext();
                postDelayed(mFlipRunnable, mFlipInterval);
            }
        }
    };

    如果是startFlipper,,也就是将下一个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是这样的简单?

  • 相关阅读:
    帮你拿下 Java 面试题!
    JavaGUI编程的宿世此生
    从事Java开发可以往那些方面发展
    java初学者都要掌握的案例
    两数之和(java)
    2020年java就业前景
    300 行代码带你秒懂 Java 多线程!
    安卓程序员如何快速入门后端开发常识
    连夜整理的Java开源项目,有后台管理类、商城类、秒杀类、支付类
    Java面试题及答案,2020年最新面试题集合
  • 原文地址:https://www.cnblogs.com/ganchuanpu/p/8406979.html
Copyright © 2011-2022 走看看