Overview
用於兩個或更多的View之間的切換,在同一時間內只有一個View將被顯示。同時我們也可以讓其自動切換,根據我們給定的時間間隔,為了不讓其切換的效果十分生硬,我們也為為其定義進入動畫和退出動畫。
常用的方法
- setFlipInterval 設置每一個View之間切換的時間的間隔
- setInAnimation 設置View 進入時候的動畫
- setOutAnimation 設置View退出時候的動畫
- startFlipping 開始播放
一個Demo
下面我們將一步步的實現上面的功能
涉及到的知識點
- 動畫(這里使用了補間動畫中的 位移動畫)
- Shape-drawable 資源 用來畫小圓點
- 手勢,用來監聽上一頁下一頁的操作
用到的素材
- 9張圖片
因為本篇的主要的內容是講解ViewFlipper,所以第一個頁面的GridView控件的使用這里就不在贅述,主要是為了功能的完善加上去的。
使用到的動畫
這里使用了4個補間動畫-位移動畫
- 從左邊進入的動畫 對應着手勢 向右邊滑
- 從右邊退出的動畫 對應着手勢向右邊滑
- 從右邊進入的動畫 對應着向左滑
- 從左邊退出的動畫 對應着向左滑
Note : 這些動畫放在了
res
目錄下anim
目錄中,如果沒有此目錄需要手動創建,關於動畫這里不再贅述,不太了解的可以參考菜鳥教程 。
left_in.xml 從左邊進入的動畫 對應着手勢 向右邊滑 ``
<?xml version="1.0" encoding="utf-8"?>
<!--圖片進入的位移動畫 從左邊向右移動-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="-100%"
android:toXDelta="0" />
right_out 從右邊退出的動畫 對應着手勢向右邊滑
<?xml version="1.0" encoding="utf-8"?>
<!--圖片退出的動畫,從左邊向右邊移動-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0"
android:toXDelta="100%" />
right_in 從右邊進入的動畫 對應着向左滑
<?xml version="1.0" encoding="utf-8"?>
<!--圖片進入的位移動畫 從右邊向左移動-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="100%"
android:toXDelta="0" />
left_out 從左邊退出的動畫 對應着向左滑
<?xml version="1.0" encoding="utf-8"?>
<!--圖片退出的動畫 從右邊向左邊移動-->
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:fromXDelta="0%"
android:toXDelta="-100%" />
shape 小圓點
這些小圓點用來指示圖片的進圖,一共有兩種格式
- 沒有被選中的狀態
- 選中狀態
Note: shape xml 文檔 放在 drawable 文件夾下
dot_selected 選中狀態的小圓點
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!--填充色-->
<solid android:color="#8F8F8F" />
<!--小圓點的邊框-->
<stroke
android:width="1dp"
android:color="#000000" />
<!--小圓點的大小-->
<size
android:width="8dp"
android:height="8dp" />
<corners android:radius="45dp" />
</shape>
dot_unselected 沒有選中的狀態
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#FFFFFF" />
<stroke
android:width="1dp"
android:color="#000000" />
<size
android:width="8dp"
android:height="8dp" />
<corners android:radius="45dp" />
</shape>
代碼
為了代碼可讀性更好一些,將進行分割為幾部分
- 全局變量
- 初始化代碼
- 手勢操作
用到的全部變量
/************
* 一些全局變量
***********/
private ViewFlipper flipper; //ViewFlipper 對象
private List<Integer> id_list; //圖片Id的集合,為了偷懶在上一個Activity總存儲成為了靜態
private LinearLayout llDots; //小點點的父容器
private List<ImageView> dotList; //所有小點點的集合
/***********
* 手勢相關的變量
***********/
private GestureDetector detector; //手勢監聽器
private int currentId; //當前圖片的索引
初始化方法
/**
* 初始化標識圖片位置的小圓點
*/
private void initDots() {
dotList = new ArrayList<ImageView>();
//根據圖片的數量來設置小圓點的數量
for (int i = 0; i < id_list.size(); i++) {
ImageView iv = new ImageView(this);
//設置包裹內容
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(-2, -2);
//設置Margin
lp.setMargins(3, 3, 3, 3);
iv.setLayoutParams(lp);
iv.setImageResource(R.drawable.dot_unselected);
//添加到dot的父容器中
llDots.addView(iv);
dotList.add(iv);
}
}
/**
* 初始化輪播的視圖
*/
private void initImageView() {
//根據圖片的數量來設置小圓點的數量
for (int i = 0; i < id_list.size(); i++) {
ImageView iv = new ImageView(this);
//設置包裹內容
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(-1, -1);
//設置Margin
iv.setLayoutParams(lp);
iv.setScaleType(ImageView.ScaleType.FIT_XY);
iv.setImageResource(id_list.get(i));
//添加到dot的父容器中
flipper.addView(iv);
}
}
/**
* 初始化手勢
*/
private void initGesture() {
detector = new GestureDetector(this, new MySimpleOnGestureListener());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_album);
id_list = HomeActivity.ID_List;
initFindView();
initDots();
initImageView();
initGesture();
//獲取到上一個Activity傳遞過來的參數
Intent intent = this.getIntent();
currentId = intent.getIntExtra("currentId", -1);
//設置當前選中的點
if (currentId != -1) {
flipper.setDisplayedChild(currentId);
dotList.get(currentId).setImageResource(R.drawable.dot_selected);
}
}
手勢操作的代碼
class MySimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener {
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
//滑動距離的絕對值
int distance = (int) Math.abs(e1.getX() - e2.getX());
//證明是向左滑動,查看下一個圖片
if (e1.getX() > e2.getX()) {
if (distance > 300) {
//設置一下相關的動畫
flipper.setInAnimation(AlbumActivity.this, R.anim.right_in);
flipper.setOutAnimation(AlbumActivity.this, R.anim.left_out);
//顯示下一個View
flipper.showNext();
//將上一個選中的dot取消
dotList.get(currentId).setImageResource(R.drawable.dot_unselected);
//計算下一張圖片應該選中的小圓點
currentId = (currentId + 1) == id_list.size() ? 0 : currentId + 1;
//選中當前的dot
dotList.get(currentId).setImageResource(R.drawable.dot_selected);
}
} else {
//證明是向右滑動,查看下一個圖片
if (distance > 300) {
//設置一下相關的動畫
flipper.setInAnimation(AlbumActivity.this, R.anim.left_in);
flipper.setOutAnimation(AlbumActivity.this, R.anim.right_out);
//顯示上一個視圖
flipper.showPrevious();
//將上一個選中的dot取消
dotList.get(currentId).setImageResource(R.drawable.dot_unselected);
//計算下一張圖片應該選中的小圓點
currentId = (currentId - 1) == -1 ? id_list.size() - 1 : currentId - 1;
//選中當前的dot
dotList.get(currentId).setImageResource(R.drawable.dot_selected);
}
}
return true;
}
}
源碼下載
http://git.oschina.net/ShareKnowledge/AndroidViewFlipperDemo