2つのアクティビティを切り替えると、画面が右から左にスライドします。戻るキーを押すと、画面が右から左にスライドします。アクティビティから戻るキーを押して画面のスライド方向を変更する方法ですか?
2 に答える
はい、可能です。バックキーイベント、または新しい画面をロードするその他のイベントをキャプチャした後、画面がスライドする方向を制御できますが、その方法は直感的にわかりません。レイアウトの最外層がコードによってアニメーション化されることはないため、レイアウトをラッパー内に配置する必要がある場合があります。また、アニメーションを発生させたい画面のonCreate()内からアニメーションコードを呼び出す必要があります。
パッケージとして「android.example」を使用して「ScreenTransitionLab」という名前のプロジェクトを作成する場合は、以下を使用して、やりたいことを達成する方法を理解するのに役立つ実用的な例を作成できます。現在、上下のトランジションに設定されていますが、左右のトランジションを使用するように簡単に変更できます。
画面全体がスライドするように変更されたメイン画面:
<?xml version="1.0" encoding="utf-8"?>
<!--
Wrapper layout whose children are to be animated. The outermost layout
used by an activity can never be animated, so this wrapper is needed.
The wrapper layout is given a different color so it can be
distinguished from the layout that is animated.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#0000FF"
>
<!-- Actual layout that is animated. -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF0000"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/btnForwards"
android:text="Forwards" />
</LinearLayout>
</LinearLayout>
画面全体がスライドするように変更された新しい画面:
<?xml version="1.0" encoding="utf-8"?>
<!--
Wrapper layout whose children are to be animated. The outermost layout
used by an activity can never be animated, so this wrapper is needed.
The wrapper layout is given a different color so it can be
distinguished from the layout that is animated.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#0000FF"
>
<!-- Actual layout that is animated. -->
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FF0000"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/btnForwards"
android:text="Forwards" />
</LinearLayout>
</LinearLayout>
NewScreenアクティビティで[戻る]ボタンがクリックされたときにアニメーション化されるScreenTransitionsLabアクティビティ:
package android.example;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class ScreenTransitionLab extends Activity {
// Layout fields
protected LinearLayout mainLayout;
public static Button btnForwards = null;
public static Activity currentActivity;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentActivity = this;
/*
* This creates View objects from the xml file. The xml file should
* define all views and all static attributes.
*/
mainLayout = (LinearLayout) getLayoutInflater().inflate(R.layout.main,
null);
btnForwards = (Button) mainLayout.findViewById(R.id.btnForwards);
btnForwards.setOnClickListener(forwardsOnClickListener);
UIHelper.setSlideDirection(mainLayout, UIHelper.bottom);
/*
* Use the Layout that contains the View objects that were modified to
* create screen that will be shown after activity is done processing
* instead of the xml file. The Layout will contain all of the views and
* static attributes that were defined in the xml file plus all of the
* dynamic attributes that were defined in the code above.
*/
setContentView(mainLayout);
}
public View.OnClickListener forwardsOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
Activity currentActivity = (Activity) v.getContext();
Intent i = new Intent(currentActivity, NewScreen.class);
currentActivity.startActivity(i);
/*
* Remove activity that is no longer current from the activity stack
* to prevent the application from bloating.
*/
currentActivity.finish();
}
};
}
ScreenTransitionsLabアクティビティで[進む]ボタンがクリックされたときにアニメーション化されるNewScreenアクティビティ:
package android.example;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
public class NewScreen extends Activity {
protected LinearLayout mainLayout;
public static Button btnBackwards = null;
public static Activity currentActivity;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
currentActivity = this;
/*
* This creates View objects from the xml file. The xml file should
* define all views and all static attributes.
*/
mainLayout = (LinearLayout) getLayoutInflater().inflate(
R.layout.new_screen, null);
btnBackwards = (Button) mainLayout.findViewById(R.id.btnBackwards);
btnBackwards.setOnClickListener(backwardsOnClickListener);
UIHelper.setSlideDirection(mainLayout, UIHelper.top);
/*
* Use the Layout that contains the View objects that were modified to
* create screen that will be shown after activity is done processing
* instead of the xml file. The Layout will contain all of the views and
* static attributes that were defined in the xml file plus all of the
* dynamic attributes that were defined in the code above.
*/
setContentView(mainLayout);
}
public View.OnClickListener backwardsOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
Activity currentActivity = (Activity) v.getContext();
Intent i = new Intent(currentActivity, ScreenTransitionLab.class);
currentActivity.startActivity(i);
/*
* Remove activity that is no longer current from the activity stack
* to prevent the application from bloating.
*/
currentActivity.finish();
}
};
}
実際にアニメーションを実行するUIHelperクラス:
package android.example;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LayoutAnimationController;
import android.view.animation.TranslateAnimation;
public class UIHelper {
public static final int top = 1;
public static final int bottom = 2;
public static final int left = 3;
public static final int right = 4;
/**
* Set direction that children in the panel will slide in from when next
* displayed.
*
* @param panel
* {@link ViewGroup} whose children will be slid in from the
* specified direction when the panel is next displayed.
* @param fromDirection
* Primitive int indicating the direction to slide the children
* of the panel from.
*/
public static void setSlideDirection(ViewGroup panel, int fromDirection) {
float fromX = 0;
float toX = 0;
float fromY = 0;
float toY = 0;
AnimationSet set = new AnimationSet(true);
Animation animation = new AlphaAnimation(0.0f, 1.0f);
animation.setDuration(100);
set.addAnimation(animation);
switch (fromDirection) {
case top:
fromX = 0.00f;
toX = 0.00f;
fromY = -1.00f;
toY = 0.00f;
break;
case bottom:
fromX = 0.00f;
toX = 0.00f;
fromY = 1.00f;
toY = 0.00f;
break;
case left:
fromX = -1.00f;
toX = 0.00f;
fromY = 0.00f;
toY = 0.00f;
break;
default:
fromX = 1.00f;
toX = 0.00f;
fromY = 0.00f;
toY = 0.00f;
break;
}
animation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, fromX,
Animation.RELATIVE_TO_SELF, toX, Animation.RELATIVE_TO_SELF,
fromY, Animation.RELATIVE_TO_SELF, toY);
animation.setDuration(200);
set.addAnimation(animation);
LayoutAnimationController controller = new LayoutAnimationController(
set, 0.25f);
panel.setLayoutAnimation(controller);
}
}
ダニーのソリューションを機能させることはできますが、それは非常に複雑です。学習したい重要なメソッドはoverridePendingTransition()です。
これが私がそれを使うためにモックアップした主な活動です。好きな方向に変換できることを示すために、垂直方向に遷移させました。
package com.superliminal.test;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class ScreenTransitionTest extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btnForwards = (Button) findViewById(R.id.btnForwards);
btnForwards.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Activity currentActivity = (Activity) v.getContext();
Intent i = new Intent(currentActivity, NewScreen.class);
// Tell the new activity how return when finished.
i.putExtra("anim id in", R.anim.down_in);
i.putExtra("anim id out", R.anim.down_out);
currentActivity.startActivity(i);
// This makes the new screen slide up as it fades in
// while the current screen slides up as it fades out.
overridePendingTransition(R.anim.up_in, R.anim.up_out);
}
});
}
}
新しい画面の実装は次のとおりです。
package com.superliminal.test;
import android.app.Activity;
import android.os.Bundle;
public class NewScreen extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.new_screen);
}
@Override
public void onBackPressed() {
this.finish();
// Use exiting animations specified by the parent activity if given
// Translate left if not specified.
overridePendingTransition(
getIntent().getIntExtra("anim id in", R.anim.left_in),
getIntent().getIntExtra("anim id out", R.anim.left_out));
}
}
レイアウトファイルは好きなものにすることができます。ラッパーレイヤーは必要ありません。これが私のmain.xmlです:
<?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"
android:background="#990000" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Main Activity" />
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/btnForwards"
android:text="Forward" />
</LinearLayout>
そして、これが私のnew_screen.xmlです。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#009900" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="New Screen. Use back button to return." />
</RelativeLayout>
他に必要なのは、res/animフォルダーに配置するアニメーションXMLファイルだけです。
up_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="-100%p" android:toYDelta="0" android:duration="1000"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />
</set>
up_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="0" android:toYDelta="100%p" android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000" />
</set>
down_in.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="100%p" android:toYDelta="0" android:duration="1000"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />
</set>
down_out.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromYDelta="0" android:toYDelta="-100%p" android:duration="1000"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="1000" />
</set>