螢幕切換指的是在同一個Activity內螢幕見的切換。
通過GestureDetector、OnGestureListener實現滑屏事件。ViewFlipper是繼承至FrameLayout的,所以它是一個Layout裡面可以放置多個View。樣本中第一頁僅放了一個按鈕BUTTON,向下滑屏時,每頁都只放了一個TEXTVIEW。
頁面:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ViewFlipper android:id="@+id/ViewFlipper01" android:layout_width="fill_parent" android:layout_height="fill_parent"> </ViewFlipper> </LinearLayout> Activity代碼:view plaincopy to clipboardprint?package com.yfz; import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.GestureDetector.OnGestureListener; import android.view.ViewGroup.LayoutParams; import android.view.animation.AnimationUtils; import android.widget.Button; import android.widget.ExpandableListView; import android.widget.TextView; import android.widget.ViewFlipper; public class Flip extends Activity implements OnGestureListener { private GestureDetector detector; private ViewFlipper flipper; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); flipper = (ViewFlipper) this.findViewById(R.id.ViewFlipper01); flipper.addView(addButtonByText("按鈕"),new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); detector = new GestureDetector(this); } public View addButtonByText(String text){ Button btn = new Button(this); btn.setText(text); return btn; } public View addTextByText(String text){ TextView tv = new TextView(this); tv.setText(text); tv.setGravity(1); return tv; } @Override public boolean onTouchEvent(MotionEvent event) { Log.i("Fling", "Activity onTouchEvent!"); return this.detector.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } /** * 監聽滑動 */ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub Log.i("Fling", "Fling Happened!"); if (e1.getX() - e2.getX() > 120) { this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_in)); this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_left_out)); this.flipper.addView(addTextByText("文字框"),new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); this.flipper.showNext(); return true; } else if (e1.getX() - e2.getX() < -120) { this.flipper.setInAnimation(AnimationUtils.loadAnimation(this,R.anim.push_right_in)); this.flipper.setOutAnimation(AnimationUtils.loadAnimation(this,R.anim.push_right_out)); this.flipper.showPrevious(); return true; } return true; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } }
這裡實現的功能是從右往左滑動則切換到上一個View,從左往右滑動則切換到下一個View,並且使用不同的in、out 動畫使轉場效果看起來統一一些。
滑屏實現:
通過android.view.GestureDetector類可以檢測各種手勢事件,該類有兩個回調介面分別用來通知具體的事件:
GestureDetector.OnDoubleTapListener:用來通知DoubleTap事件,類似於滑鼠的雙擊事件,該介面有如下三個回呼函數:
1. onDoubleTap(MotionEvent e):通知DoubleTap手勢,
2. onDoubleTapEvent(MotionEvent e):通知DoubleTap手勢中的事件,包含down、up和move事件(這裡指的是在雙擊之間發生的事件,例如在同一個地方雙擊會產生DoubleTap手勢,而在DoubleTap手勢裡面還會發生down和up事件,這兩個事件由該函數通知);
3. onSingleTapConfirmed(MotionEvent e):用來判定該次點擊是SingleTap而不是DoubleTap,如果連續點擊兩次就是DoubleTap手勢,如果只點擊一次,系統等待一段時間後沒有收到第二次點擊則判定該次點擊為SingleTap而不是DoubleTap,然後觸發SingleTapConfirmed事件。
GestureDetector.OnGestureListener:用來通知普通的手勢事件,該介面有如下六個回呼函數:
1. onDown(MotionEvent e):down事件;
2. onSingleTapUp(MotionEvent e):一次點擊up事件;
3. onShowPress(MotionEvent e):down事件發生而move或則up還沒發生前觸發該事件;
4. onLongPress(MotionEvent e):長按事件;
5. onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY):滑動手勢事件;
6. onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY):在螢幕上拖動事件。
本次僅用到了OnGestureListener類中的onFling方法。 其他手勢事件各位可以自己回去實驗。
簡單說明:
要實現螢幕切換的話,首先需要定義一個GestureDetector:
private GestureDetector mGestureDetector;
並在onCreate函數中初始化:
mGestureDetector = new GestureDetector(this);
同時Activity要繼承OnGestureListener介面,並實現其中的onFling方法。
另外Activity的onTouchEvent事件也要實現!!
另外本例View切換時還有動畫效果。使用Animation類實現,相關的函數:
setInAnimation:設定View進入螢幕時候使用的動畫,該函數有兩個版本:
一個接受單個參數,類型為android.view.animation.Animation;
一個接受兩個參數,類型為Context和int,分別為Context對象和定義Animation的resourceID。
setOutAnimation: 設定View退出螢幕時候使用的動畫,參數setInAnimation函數一樣。
showNext: 調用該函數來顯示FrameLayout裡面的下一個View。
showPrevious: 調用該函數來顯示FrameLayout裡面的上一個View。
動畫源檔案: (在res目錄下,建立一個anim檔案夾,把下面的檔案都放在這裡)
push_left_in.xml
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
push_left_out.xml:
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>
push_right_in.xml:
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%p" android:toXDelta="0"
android:duration="500" />
<alpha android:fromAlpha="0.1" android:toAlpha="1.0"
android:duration="500" />
</set>
push_right_out.xml:
view plaincopy to clipboardprint?
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="100%p"
android:duration="500" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.1"
android:duration="500" />
</set>