如何寫一個翻頁的功能

如何使用ImageView寫滑動跟縮放的功能裡面,
我們示範了怎麼放大縮小的功能,
但是如果要寫一個看照片/電子書/漫畫...等等的app,
只需要再加上翻頁的功能, 就可以完成一個簡易看漫畫的App。

一開始的畫面

放大




翻頁

翻頁後圖示會恢復正常大小

回上一頁


直接拿如何寫一個圖片滑動跟縮放的功能的程式碼來改,

由於看漫畫或者電子書有版權問題, 因此我就用幾張簡單的圖片,
模擬抓好的圖片檔放置專案內, 如果有需要, 可以自行改成從網路上抓取,
或者放再sdcard之下圖片檔。

一開始直接把要放的圖片, 放進res/drawable/之下, 並且宣告成為陣列,
用來假裝是我們要觀看的漫畫。
        //這邊只需要換成sdcard的圖片陣列 就可以仿一個看漫畫的app
 private int[] images = {
  R.drawable.cat, R.drawable.flower, R.drawable.hippo,
         R.drawable.monkey, R.drawable.mushroom, R.drawable.panda,
         R.drawable.rabbit, R.drawable.raccoon
 };

接著我們在setImageSize()這個方法內, imageView事件中的ACTION_POINTER_UP事件,
做一些修改, 即可完成我們這次翻頁的功能。
//如果進入左邊30個px 則代表換下一張圖 
    if(event.getX()<30){
        imageIndex--;
        if(imageIndex<0) imageIndex = images.length-1;
        else if(imageIndex>7) imageIndex = 0;
        camera.save();//用來儲存最初的狀態

        imageView.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_out_left));
        camera.getMatrix(matrix);
        imageView.setImageResource(images[imageIndex]);

        imageView.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.slide_in_right));

        center();
        camera.restore();//還原最初的狀態
                 
   }

   else if(event.getX()>dm.widthPixels-30){//如果進入右邊30px 則代表換成上一張圖

       imageIndex++;
       if(imageIndex<0) imageIndex = images.length-1;
       else if(imageIndex>7) imageIndex = 0;

       camera.save();

       imageView.startAnimation(AnimationUtils.loadAnimation(mContext, android.R.anim.slide_out_right));

       camera.getMatrix(matrix);
       imageView.setImageResource(images[imageIndex]);

       imageView.startAnimation(AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left));

       center();
       camera.restore();
   }

說明一下, 我們要左右兩邊進行翻頁的動作,
但是要怎麼判斷我們手勢是往左滑, 還是往右滑呢?
很簡單,
因為我們手指是跟著圖片進行移動,
因此, 只要圖片的左半邊x軸超過螢幕大小,
並且手指放開了, 那麼我們就可以判定, 使用者是想要翻上一頁來看,
反之同理。

那麼在翻頁的時候, 我們就對ImageView加入一些動畫效果,
由於在android當中已經對所有view設置可以加入動畫效果,
而我們又不需要太複雜的動畫, 只要左出右進即可,
所以使用預設功能, 就很方便了。

但是我找了一下, google似乎內建的動畫效果只有右出左近,
去翻了一下android source code,
結果發現framework層已經有加入右進左出的動畫效果,
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/frameworks/base/core/res/res/anim/slide_in_right.xml
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.5_r1/frameworks/base/core/res/res/anim/slide_out_left.xml
所以只要拿過來用, 即可。

slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromXDelta="50%p" android:toXDelta="0"

            android:duration="@android:integer/config_mediumAnimTime"/>

<alpha android:fromAlpha="0.0" android:toAlpha="1.0"

            android:duration="@android:integer/config_mediumAnimTime" />

</set>

slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">

<translate android:fromXDelta="0" android:toXDelta="-50%p"

            android:duration="@android:integer/config_mediumAnimTime"/>

<alpha android:fromAlpha="1.0" android:toAlpha="0.0"

            android:duration="@android:integer/config_mediumAnimTime" />

</set>

將這兩個檔案放進/res/anim/之下即可。


imageIndex--;
if(imageIndex<0) imageIndex = images.length-1;
else if(imageIndex>7) imageIndex = 0;

...

imageIndex++;
if(imageIndex<0) imageIndex = images.length-1;
else if(imageIndex>7) imageIndex = 0;
你會發現, 我在左右翻頁的時候, 加入一些計算,
一開始imageIndex設定為0, 代表我們要讀取圖片的第一張,
但是超過圖片陣列大小的時候,
我們就讓他回到第一頁(這邊看個人需求, 如果你要讓他停在最後一頁也可以)
反之, 如果小於0, 則讓他回到最後一頁。


當我們進行翻頁的時候, 利用Camera物件, 讓我們的ImageView回復到最初的大小,
因為有時候, 使用者放大或縮小完以後, 就直接翻下一頁,
如果看漫畫的時候, 放大看完, 直接翻頁是很正常的舉動,
因此我們就必須讓程式能自己回復正常大小, 方便使用者繼續觀看。
camera.save();

imageView.startAnimation(AnimationUtils.loadAnimation(mContext, android.R.anim.slide_out_right));
camera.getMatrix(matrix);
imageView.setImageResource(images[imageIndex]);

imageView.startAnimation(AnimationUtils.loadAnimation(mContext, android.R.anim.slide_in_left));
center();

camera.restore();


那麼這樣就簡單完成一個翻頁的功能了。



程式碼
http://uploadingit.com/file/q0x6pumrctjzwn21/DragImageDemo2.zip