Rso's Jotter

日々の開発の知見のメモやその他雑記

フリック入力で複数のページの切り替え

ViewFlipperとアニメーションを使えばフリック入力による画面の切り替えを行うことができる。
フリック入力の取得、画面の切り替えは他のページでもいろいろ載っているけど、このあたりのページを参考にした。

フリックで画面を横スクロールする方法



しかしこの方法では切り替えたい画面の数だけViewFlipperの中にビューを作成することになるので、リソースがもったいない。

そこでViewFlipperの中のビューは2つだけにして、切り替え時に次の画面、前の画面をselectorで管理するようにしてみた。


アニメーションの定義

アニメーションの定義。これは左からスライドインするアニメーションの動きだが、同様にスライドアウト、右からのスライドイン、スライドアウトの4つを作成する。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator" >
	  <translate android:duration="300" 
	android:fromXDelta="-100%p" android:toXDelta="0%p"
	android:fromYDelta="0%p" android:toYDelta="0%p"
	android:fillAfter="true"  android:fillEnabled="true"/>
</set>

レイアウトの定義

ViewFlipperの中にはビュー(今回はTextView)を2つだけ定義

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

    <ViewFlipper
        android:id="@+id/viewFlipper1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:textSize="32pt" />

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:textSize="32pt" />
    </ViewFlipper>

</LinearLayout>

Activity

public class FlipperTestActivity extends Activity{
    
	//アニメーション
	Animation mInFromLeft;
	Animation mInFromRight;
	Animation mOutToLeft;
	Animation mOutToRight;
	
	GestureDetector mGestureDetector;

	ViewFlipper mViewFlipper;

	int index = 0;

	/**
	 * 表示したい画面を管理するセレクタ
	 * @author a-saitoh
	 *
	 */
	class Selector{
		//この文字列が今回切り替えたい内容とする
		String[] strs = {"Text1", "Text2", "Text3", "Text4", "Text5"};
		List<String> list = (List<String>) Arrays.asList(strs);
		int index;
		
		public Selector(){
			index = 0;
		}
		
		public String get(){
			return list.get(index);
		}
		
		public String next(){
			if(index == list.size() -1 ){
				index = 0;
				return list.get(index);
			}
			return list.get(++index);
		}
		
		public String getNext(){
			if(index == list.size() -1 ){
				return list.get(0);
			}
			return list.get(index + 1);
		}
		
		public String prev(){
			if(index == 0){
				index = list.size() - 1;
				return list.get(index);
			}
			return list.get(--index);
		}
		
		public String getPrev(){
			if(index == 0){
				return list.get(list.size() - 1);
			}
			return list.get(index - 1);
		}
	}
	
	
	 TextView mTextView01;
	 TextView mTextView02;
	 Selector selector = new Selector();

	 
	  // タッチ処理リスナー
    OnTouchListener mTouchListener = new OnTouchListener() {

		public boolean onTouch(View v, MotionEvent event) {
			Log.v("test", "ontouch");
			if (mGestureDetector.onTouchEvent(event)){
        	  return true;
          }

			return false;
		}

    };

		 OnGestureListener mGestureListener = new OnGestureListener(){

			public boolean onDown(MotionEvent e) {
				Log.v("test", "on down");
				return true;
			}

			public boolean onFling(MotionEvent e1, MotionEvent e2,
					float velocityX, float velocityY) {
				Log.v("test", "on Fling");
				float dx = Math.abs(velocityX);
				float dy = Math.abs(velocityY);
				
				if(dx > dy || dx > 150){
					if(e1.getX() < e2.getX()){
						Log.v("test", "child" + mViewFlipper.getDisplayedChild());
						TextView v = (TextView)mViewFlipper.getChildAt( mViewFlipper.getDisplayedChild() ^ 1);
						Log.v("test", "LEFT" + v.getText());
						v.setText(selector.prev());
						
						mViewFlipper.setInAnimation(mInFromLeft);
						mViewFlipper.setOutAnimation(mOutToRight);
						mViewFlipper.showNext();
					}else{
						Log.v("test", "child" + mViewFlipper.getDisplayedChild());
						TextView v = (TextView)mViewFlipper.getChildAt(mViewFlipper.getDisplayedChild() ^ 1);
						Log.v("test", "Right" + v.getText());
						v.setText(selector.next());

						mViewFlipper.setInAnimation(mInFromRight);
						mViewFlipper.setOutAnimation(mOutToLeft);
						mViewFlipper.showPrevious();
					}
					
				}
				return false;
			}

			public void onLongPress(MotionEvent e) {
				// TODO Auto-generated method stub
				Log.v("test", "on LongPress");
			}

			public boolean onScroll(MotionEvent e1, MotionEvent e2,
					float distanceX, float distanceY) {
				// TODO Auto-generated method stub
				return false;
			}

			public void onShowPress(MotionEvent e) {
				// TODO Auto-generated method stub
				
			}

			public boolean onSingleTapUp(MotionEvent e) {
				// TODO Auto-generated method stub
				return false;
			}
			 
		 };
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTextView01 = (TextView)findViewById(R.id.textView1);        
        mTextView02 = (TextView)findViewById(R.id.textView2);        
        mViewFlipper = (ViewFlipper) findViewById(R.id.viewFlipper1);
        // ジェスチャーを生成
        mGestureDetector = new GestureDetector(this, mGestureListener);

        // アニメーションを生成
        mInFromLeft = AnimationUtils.loadAnimation(this, R.anim.in_from_left);
        mOutToRight = AnimationUtils.loadAnimation(this, R.anim.out_to_right);
        mInFromRight = AnimationUtils.loadAnimation(this, R.anim.in_from_right);
        mOutToLeft = AnimationUtils.loadAnimation(this, R.anim.out_to_left);
        
        mTextView01.setOnTouchListener(mTouchListener);
        mTextView02.setOnTouchListener(mTouchListener);
        mTextView01.setText(selector.get());
        mTextView02.setText(selector.getNext()); 
    }
}

結果

スクリーンショットでは良くわからないけど、ビュー2つで複数の画面を切り替えることができる。