Android之ViewFlipper的簡單使用

你們都使用過ViewPager,可是ViewPager還有一個兄弟,那就是ViewFlipper。二者的名字很是類似,咱們能夠將ViewPager理解成「一頁一頁的視圖」,ViewFlipper則是「快速翻轉的視圖」,但後者的使用率卻遠不及前者,不過這並不意味着ViewFlipper就弱了。如今咱們就來拜訪一下常常被冷落的ViewFlipper。html

一、建立工程及頁面視圖佈局

在Android Studio中新建一個工程,實現這樣一個效果:建立紅、橙、綠、藍四種顏色的頁面,而後經過ViewFlipper讓它們來回切換。四個頁面佈局文件的名稱以下所示:java

四個頁面佈局名稱

item_view1.xml的代碼以下:android

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="@android:color/holo_red_light"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</LinearLayout>

另外三個佈局的代碼只要把背景色換掉就能夠了。git

二、添加布局至ViewFlipper

頁面建立好了,那咱們怎麼把它放置到ViewFlipper中呢?很簡單,ViewFlipper支持include標籤添加頁面,咱們只需在activity_main.xml中將四個佈局依次include進去便可。github

直接運行就能夠看到下面的效果了:
切換效果圖segmentfault

除了直接在佈局文件中添加頁面外,也能夠在代碼中添加,把activity_mai.xml中include標籤註釋掉,而後在MainActivity中初始化ViewFlipper以後再添加以下的代碼:ide

//要添加的頁面佈局ID
    private int viewIds[] = {R.layout.item_view1, R.layout.item_view2, R.layout.item_view3, R.layout.item_view4};
    /**
     * 將頁面添加進ViewFlipper
     */
    private void addViews() {
        View itemView;
        for (int viewId : viewIds) {
            itemView = View.inflate(this,viewId,null);
            viewFlipper.addView(itemView);
        }
    }

而後在onCreate中調用addViews方法便可。佈局

三、添加頁面切換動畫

頁面切換的效果咱們是實現了,可是沒有變化過程,看起來太生硬了,累眼睛。若是能有動畫效果的話就會舒服不少。這裏,咱們就要用到兩個新屬性了:動畫

  • inAnimation:視圖進入時的動畫效果this

  • outAnimation:視圖退出時的動畫效果
    這兩個屬性也能夠在代碼中設置的,稍後咱們會用到。如今,咱們就建立所須要的動畫文件。好比,我想要實現左右循環滑動的動畫效果,那麼就能夠分紅兩種狀況來討論:一種是新的視圖從左邊進入,原有的視圖從右邊退出,即從左往右滑動;另外一種是新視圖從右邊進入,原有的視圖從左邊退出,即從右往左滑動。弄清楚全部的動畫效果以後,咱們就在res文件夾下新建一個anim文件夾,建立以下以下四種動畫效果:

left_in.xml
視圖從左邊進入界面的動畫:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="-100%p"
        android:toXDelta="0"/>
</set>

left_out.xml
視圖從左邊退出界面的動畫:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="-100%p"/>
</set>

right_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="100%p"
        android:toXDelta="0"/>
</set>

right_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="500"
        android:fromXDelta="0"
        android:toXDelta="100%p"/>
</set>

如今咱們先來試試從左往右轉的動畫效果。在佈局中給ViewFlipper加上以下的屬性:

android:inAnimation="@anim/left_in"
        android:outAnimation="@anim/right_out"

運行一下,就能夠實現從左往右滑動的動畫效果了(GIF圖有點失真,不過效果是沒問題的)。

從左往右滑動的動畫

相信不用我說,你也知道怎麼讓它從右往左滑動了吧?

四、手指左右滑屏一(使用觸摸監聽事件實現)

看着畫面自顧自地滑動,是否是心癢癢的?不要緊,下面咱們就來讓它響應咱們手指的滑動。在此以前,先作點準備工做:前往佈局文件,去掉動畫屬性,並將autoStart屬性設爲false。

要讓它遵從「指揮」,咱們能夠先繼承OnTouchListener接口,而後實現onTouch方法:

private float startX; //手指按下時的x座標
    private float endX; //手指擡起時的x座標
    private float moveX = 100f; //判斷是否切換頁面的標準值
    /**
     * 觸摸監聽事件
     * @param v
     * @param event
     * @return
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                //手指按下時獲取起始點座標
                startX = event.getX();
                break;
            case MotionEvent.ACTION_UP:
                //手指擡起時獲取結束點座標
                endX = event.getX();
                //比較startX和endX,判斷手指的滑動方向
                if (endX - startX > moveX) { //手指從左向右滑動
                    viewFlipper.setInAnimation(this, R.anim.left_in);
                    viewFlipper.setOutAnimation(this, R.anim.right_out);
                    viewFlipper.showPrevious();
                } else if (startX - endX > moveX) { //手指向右向左滑動
                    viewFlipper.setInAnimation(this, R.anim.right_in);
                    viewFlipper.setOutAnimation(this, R.anim.left_out);
                    viewFlipper.showNext();
                }
                break;
        }
        return true;
    }

上面的代碼不難,註釋也寫得比較清楚了。整體的思路就是獲取手指按下和擡起時的座標,而後判斷是向左仍是向右滑動。值得注意的是showPreviousshowNext方法,前者是顯示上一個視圖,後者則是顯示後一個視圖。最後還要記住,返回值要改成true,不然觸摸事件是沒法響應的。

效果圖以下,能夠向左,也能夠向右。
手指滑屏

五、手指左右滑屏二(使用手勢監聽事件實現)

除了觸摸監聽事件以外,咱們也能夠用手勢監聽事件OnGestureListener實現一樣的效果,但繼承了該接口以後要實現一連串的方法,代碼一會兒膨脹起來了,而咱們須要的只是其中一個方法啊。好在Android還提供了一個類SimpleOnGestureListener,這樣咱們只要自定義一個類繼承它,而後實現咱們須要的方法就能夠了:

//建立手勢監聽器
    GestureDetector gestureDetector = new GestureDetector(this, new MyGestureListener());

    /**
     * 自定義手勢監聽類
     */
    class MyGestureListener extends GestureDetector.SimpleOnGestureListener{
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            if (e2.getX() - e1.getX() > moveX){
                viewFlipper.setInAnimation(MainActivity.this, R.anim.left_in);
                viewFlipper.setOutAnimation(MainActivity.this, R.anim.right_out);
                viewFlipper.showPrevious();
            } else if (e2.getX() - e1.getX() < moveX){
                viewFlipper.setInAnimation(MainActivity.this, R.anim.right_in);
                viewFlipper.setOutAnimation(MainActivity.this, R.anim.left_out);
                viewFlipper.showNext();
            }
            return true;
        }
    }

這裏的onFling方法得解釋一下,它表示的是手指在屏幕上移動而後鬆開的手勢,也就是滑動。前面兩個參數分別表示手指按下和鬆開時的事件,經過它們的對象去調用getX()方法就能夠獲取滑動先後的座標了。後面的步驟就跟咱們在觸摸事件裏面的同樣,相信你能理解的。

我一開始覺得到這裏就大功告成了,可運行以後卻紋絲不動!仔細查看文檔,發現還必須到觸摸監聽方法中調用onTouchEvent方法才行,不然觸摸事件不會起做用的。

@Override
    public boolean onTouch(View v, MotionEvent event) {
        gestureDetector.onTouchEvent(event);
        return true;
    }

六、後記

ViewFlipper的用法就告一段落了,寫這篇文章的時候我還順便複習了手勢監聽事件等知識,也但願你能有所收穫。下面是源碼:
ViewFlipperDemo

七、參考文章

谷歌官方文檔之ViewFlipper
Android的手勢操做識別

相關文章
相關標籤/搜索