AndroidアプリでBB2Cっぽいアクティビティーの移動


iPhoneアプリのBB2Cのようなアクティビティーの遷移ができないかと思い、いろいろ調べながら作ってみた。

(実機ではまだ試していない)

Activity1⇔Activity2を行き来するのを想定しています。

activityAnime.java

右にフリックした場合は新しいアクティビティーを呼び出します。

フリックの判断はonFlingから得られたvelocityXとvelocityYの絶対値から何となく出していますが、精度が悪い場合は判定の調整をすればよい。


public class activityAnime extends Activity {
 /** Called when the activity is first created. */
 private GestureDetector gestureDetector;

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);

 setContentView(R.layout.main);

 gestureDetector = new GestureDetector(this, simpleOnGestureListener);

 Button bt = (Button) findViewById(R.id.Button01);
 bt.setOnClickListener(new OnClickListener(){
 public void onClick(View v){
 Intent intent = new Intent(getBaseContext(), activityAnime2.class);
 startActivity(intent);
 }
 });
 }

 public boolean onTouchEvent(MotionEvent event){
 gestureDetector.onTouchEvent(event);

 return true;
 }

 private final SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener(){
 @Override
 public boolean onDoubleTap(MotionEvent event) {
 super.onDoubleTap(event);
 return true;
 }

 @Override
 public boolean onDoubleTapEvent(MotionEvent event) {
 super.onDoubleTapEvent(event);
 return true;
 }

 @Override
 public boolean onDown(MotionEvent event) {
 super.onDown(event);
 return true;
 }

 @Override
 public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
 super.onFling(event1, event2, velocityX, velocityY);

 if(velocityX < 0){
 if(Math.abs(velocityX) > Math.abs(velocityY)){

 // 左にフリック
 Intent intent = new Intent(activityAnime.this, activityAnime2.class);
 startActivity(intent);
 }
 }
 else if(velocityX > 0){
 if(Math.abs(velocityX) > Math.abs(velocityY)){
 // 右にフリック
 }
 }
 return true;
 }

 @Override
 public void onLongPress(MotionEvent event) {
 super.onLongPress(event);
 }

 @Override
 public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) {
 super.onScroll(event1, event2, distanceX, distanceY);
 return true;
 }

 @Override
 public void onShowPress(MotionEvent event) {
 super.onShowPress(event);
 }

 @Override
 public boolean onSingleTapConfirmed(MotionEvent event) {
 super.onSingleTapConfirmed(event);
 return true;
 }

 @Override
 public boolean onSingleTapUp(MotionEvent event) {
 super.onSingleTapUp(event);
 return true;
 }
 };
}

activityAnime2.java

右にフリックした場合にこのアクティビティーを終了させます。フリックの取得方法は同じです。


public class activityAnime2 extends Activity {
 /** Called when the activity is first created. */
 private GestureDetector gestureDetector;

 @Override
 public void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.main2);

 gestureDetector = new GestureDetector(this, simpleOnGestureListener);

 Button bt = (Button) findViewById(R.id.Button01);
 bt.setOnClickListener(new OnClickListener(){
 public void onClick(View v){
 finish();
 }
 });
 }

 public boolean onTouchEvent(MotionEvent event){
 gestureDetector.onTouchEvent(event);
 return true;
 }

 private final SimpleOnGestureListener simpleOnGestureListener = new SimpleOnGestureListener(){
 @Override
 public boolean onDoubleTap(MotionEvent event) {
 super.onDoubleTap(event);
 return true;
 }

 @Override
 public boolean onDoubleTapEvent(MotionEvent event) {
 super.onDoubleTapEvent(event);
 return true;
 }

 @Override
 public boolean onDown(MotionEvent event) {
 super.onDown(event);
 return true;
 }

 @Override
 public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {
 super.onFling(event1, event2, velocityX, velocityY);
 if(velocityX < 0){
 if(Math.abs(velocityX) > Math.abs(velocityY)){
 // 左にフリック
 }
 }
 else if(velocityX > 0){
 if(Math.abs(velocityX) > Math.abs(velocityY)){
// 右にフリック

// アクティビティー終了

finish();
 }
 }
 return true;
 }

 @Override
 public void onLongPress(MotionEvent event) {
 super.onLongPress(event);
 }

 @Override
 public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX, float distanceY) {
 super.onScroll(event1, event2, distanceX, distanceY);
 return true;
 }

 @Override
 public void onShowPress(MotionEvent event) {
 super.onShowPress(event);
 }

 @Override
 public boolean onSingleTapConfirmed(MotionEvent event) {
 super.onSingleTapConfirmed(event);
 return true;
 }

 @Override
 public boolean onSingleTapUp(MotionEvent event) {
 super.onSingleTapUp(event);
 return true;
 }
 };
}

以上でフリック時のアクティビティーの切り替えは可能になったがページ遷移時のアニメーションが欲しい。

こちらのブログで詳しく解説されていらっしゃったので参考にさせていただき使わせていただきました(この辺のことが未だによくわからない。。。)

res/values/theme.xml

テーマを設定する


<?xml version="1.0" encoding="UTF-8"?>
<resources>
 <style name="AnimationTheme" parent="android:Theme">
 <item name="android:windowAnimationStyle">@style/AnimationActivity</item>
 </style>
</resources>

res/values/style.xml

各アニメーションのスタイルを設定する


<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AnimationActivity" parent="android:Animation.Activity">
<item
 name="android:activityOpenEnterAnimation">@anim/open_enter</item>
<item
 name="android:activityOpenExitAnimation">@anim/open_exit</item>
<item
 name="android:activityCloseEnterAnimation">@anim/close_enter</item>
<item
 name="android:activityCloseExitAnimation">@anim/close_exit</item>
</style>
</resources>

res/anim/close_enter.xml

activity2が閉じるときのactivity1のアニメーション


<?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:fromXDelta="-100%"
 android:toXDelta="0%"
 android:duration="300"
 android:fillAfter="true"
 android:fillEnabled="true"/>
</set>

res/anim/close_exit.xml

activity2が閉じるときのactivity2のアニメーション


<?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:fromXDelta="0%"
 android:toXDelta="100%"
 android:duration="300"
 android:fillAfter="true"
 android:fillEnabled="true"/>
</set>

res/anim/open_enter.xml

activity2が開くときのactivity2のアニメーション


<?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:fromXDelta="100%"
 android:toXDelta="0%"
 android:duration="300"
 android:fillAfter="true"
 android:fillEnabled="true"/>
</set>

res/anim/open_exit.xml

activity2が開くときのactivity1のアニメーション


<?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:fromXDelta="0%"
 android:toXDelta="-100%"
 android:duration="300"
 android:fillAfter="true"
 android:fillEnabled="true"/>
</set>

後はManifextファイルに設定したテーマを各アクティビティーに指定する


<activity ・・・  android:theme="@style/AnimationTheme">

しかし大量な使わないメソッドが邪魔すぎる。何とかならないのか・・・

yagi