前置き
- NavigationDrawerを実装するときにざっくり調べた(Google先生に翻訳してもらっただけともいう)のでメモ
- AndroidManifest.xmlのactivity はActivityInfo.metadataで参照できる
- これを使えばNavigationDrawerを複数Activityに表示したときの遷移が簡単に出来る
調べたメソッドとか
- Intent getParentActivityIntent(Activity activity);
- boolean shouldUpRecreateTask(Activity activity, Intent targetIntent);
- void navigateUpTo(Activity activity, Intent upIntent);
- String getParentActivityName(Context context, ActivityInfo info);
boolean shouldUpRecreateTask(Activity activity, Intent targetIntent);
Returns true if sourceActivity should recreate the task when navigating 'up' by using targetIntent.
引数のtargetIntentを使用してNavigationUpを実行するときに、UP先のActivity(タスク)を生成する必要がある場合にはtrueを返す。
If this method returns false the app can trivially call navigateUpTo(android.app.Activity,android.content.Intent) using the same parameters to correctly perform up navigation.
このメソッドがfalseであるなら、使用したパラメタのtargetIntentを使うことでNavUtils.navigateUpTo(activity,targetIntent)によりNavigation Upが実行できる。
If this method returns true, the app should synthesize a new task stack by using TaskStackBuilder or another similar mechanism to perform up navigation.
逆にtrueであるなら、ナビゲーションを実行するためにTaskStackBuilderなどを使って新しいタスクのスタックを作る必要がある。
要は引数のactivityからtargetIntentへNavigationUpするときに、遷移先が存在するかを判定するメソッド。
Androidでは、同一アプリでも異なるタスクを形成できる事(singleInstanceが設定されたActivityは別タスク)や、他のアプリからのIntentを受け入れてActivityを起動できる事から、遷移元と遷移先が同一のタスクとは限らないことが起きるため。
サンプルコード
Intent upIntent = NavUtils.getParentActivityIntent(this);
if(NavUtils.shouldUpRecreateTask(this,upIntent)){
// up先のタスクがないので生成するなど
TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivites();
}else{
// 存在してるのでそのままupする
NavUtils.navigateUpTo(this,upIntent);
}
void navigateUpFromSameTask(Activity sourceActivity)
Convenience method that is equivalent to calling navigateUpTo(sourceActivity, getParentActivityIntent (sourceActivity)). sourceActivity will be finished by this call.
navigateUpTo(sourceActivity, getParentActivityIntent (sourceActivity))を実行するのと同じ簡易メソッド。引数のsourceActivityはこのメソッド実行時に終了される。
Note: This method should only be used when sourceActivity and the corresponding parent are within the same task. If up navigation should cross tasks in some cases, see shouldUpRecreateTask(android.app.Activity,android.content.Intent).
このメソッドは引数のsourceActivityと親のタスクが同一のタスクに存在する場合に使う。
shouldUpRecreateTaskを使って自分のActivityとnavigateUpToの先が同一のタスクであるか確認してから使う必要がある。
void navigateUpTo(Activity sourceActivity, Intent upIntent)
Navigate from sourceActivity to the activity specified by upIntent, finishing sourceActivity in the process.
sourceActivityで指定したActivityからupIntentに対してNavigationUpを実行する。このとき、sourceActivityは破棄される。
upIntent will have the flag android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP set by this method, along with any others required for proper up navigation as outlined in the Android Design Guide.
Androidのガイドライにもある通り、最適ナビゲーションを実現するため、この時のupIntentに対してはandroid.content.Intent.FLAG_ACTIVITY_CLEAR_TOPがセットされた状態で実行される。
(FLAG_ACTIVITY_CLEAR_TOPがついてると親のActivityが再生成されたように見えるがこれが標準)
(singleTopにすると二回目以降のIntent呼び出して召喚された時に、新しくインスタンスを生成せずに再利用する。このため、navigateUpToで遷移するときにはちょうどいい)
(ただしこのときはActivity#onCreate()ではなく、Activity#onNewIntent()から実行されるので注意)
(singleTopなActivityが破棄されたり、Activityを保持しないなどした時にどうなるかは不明)
This method should be used when performing up navigation from within the same task as the destination. If up navigation should cross tasks in some cases, see shouldUpRecreateTask(android.app.Activity,android.content.Intent).
up先のActivityと同一タスク内でナビゲーションを行なう場合はこれを使う必要がある。遷移先、遷移元のタスクが同一であるかについては、先のメソッドと同じようにshouldUpRecreateTaskを用いる。
Intent getParentActivityIntent(Activity sourceActivity)
Obtain an android.content.Intent that will launch an explicit target activity specified by sourceActivity's PARENT_ACTIVITY element in the application's manifest.
sourceActivityで指定されたActivityの親となるActivityへの遷移Intentを取得する。
これは、AndroidManifest.xmlの、PARENT_ACTIVITYを使って定義されている必要がる。
If the device is running Jellybean or newer, the android:parentActivityName attribute will be preferred if it is present.
デバイスがJellyBeans以降であるなら、AndroidManifest.xmlにandroid:parentActivityNameアトリビュートが使えるのでこっちを使う。これはPARENT_ACTIVITYよりも優先される。
また、getParentActivityIntentには、引数としてContextとClassやContextとComponentNameなどで代替するメソッドもある。
String getParentActivityName(Context context, ActivityInfo info);
Return the fully qualified class name of sourceActivity's parent activity as specified by a PARENT_ACTIVITY element within the activity element in the application's manifest.
AndroidManifest.xmlにPARENT_ACTIVITYがセットされてるなら、それをもとにしてActivityInfoから親Activityのクラス名を取得する。引数にContextとComponentNameのやつもある。