web-dev-qa-db-ja.com

どうすれば正しく親アクティビティに戻ることができますか?

私のAndroidアプリケーションには2つのアクティビティ(AとB)があり、アクティビティAからアクティビティBに移動するためにインテントを使用しています。parent_activityの使用が有効になっています。

 <activity
        Android:name=".B"
        Android:label="B" >
        <meta-data
            Android:name="Android.support.PARENT_ACTIVITY"
            Android:value="com.example.app_name.A" />
  </activity>

UPボタンを提供するテーマも使います。

したがって、アクティビティBIを呼び出した後、BIはUPボタンを使用してアクティビティAに戻ることができます。問題は、アプリケーションがonCreate() - アクティビティAの関数を呼び出すことです。これもまた必要な動作ではありません。アクティビティBを呼び出す前と同じように見えるようにするには、アクティビティAが必要です。

これを達成する方法はありますか?

前もって感謝します

編集:

アクティビティーAからアクティビティーBを開始するコードを作成しませんでした。Eclipseによって自動生成されると思います。

クラスBは次のようになります。

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_b, menu);
    return true;
}


@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case Android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
    }
    return super.onOptionsItemSelected(item);
}
169
ashiaka

Androidマニフェストで標準launchModeを使用してアクティビティAを宣言しました。 ドキュメント によると、次のことを意味します。

システムは、常にターゲットタスクでアクティビティの新しいインスタンスを作成し、インテントをそれにルーティングします。

したがって、タスクスタックが正しく処理された場合でも、システムはアクティビティAの再作成(つまり、onCreateの呼び出し)を強制されます。

この問題を修正するには、マニフェストを変更して、次の属性をAアクティビティ宣言に追加する必要があります。

Android:launchMode="singleTop"

注:finish()(以前の解決策として提案されたように)を呼び出しても動作しますonly完全に確実終了するアクティビティBインスタンスは、アクティビティAのインスタンスの上に存在します。より複雑なワークフロー(たとえば、通知からアクティビティBを起動する)では、その場合、BからアクティビティAを正しく起動する必要があります。

326
LorenzCK

更新回答:アップナビゲーションデザイン

どのアクティビティが各アクティビティの適切な親であるかを宣言する必要があります。そうすることで、システムはマニフェストファイルから論理的な親アクティビティを判断できるため、システムはUpなどのナビゲーションパターンを容易にすることができます。

そのためには、あなたは親のActivityをattribute付きのActivityタグで宣言しなければなりません。

Android:parentActivityName

好きです、

<!-- The main/home activity (it has no parent activity) -->
    <activity
        Android:name="com.example.app_name.A" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        Android:name=".B"
        Android:label="B"
        Android:parentActivityName="com.example.app_name.A" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            Android:name="Android.support.PARENT_ACTIVITY"
            Android:value="com.example.app_name.A" />
    </activity>

このように宣言された親アクティビティで、以下のように適切な親まで上に移動できます。

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Respond to the action bar's Up/Home button
    case Android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

そのため、このメソッドをNavUtils.navigateUpFromSameTask(this);と呼び出すと、現在のアクティビティを終了して適切な親アクティビティを開始(または再開)します。ターゲットの親アクティビティがタスクのバックスタックにある場合は、FLAG_ACTIVITY_CLEAR_TOPの定義に従って前方に移動されます。

そしてUpボタンを表示するためにはsetDisplayHomeAsUpEnabled():を宣言しなければなりません

@Override
public void onCreate(Bundle savedInstanceState) {
    ...
    getActionBar().setDisplayHomeAsUpEnabled(true);
}

旧回答:(アップナビゲーションなし、デフォルトのバックナビゲーション)

アクティビティBからアクティビティAを再開した場合にのみ発生します。

startActivity()を使う.

これの代わりに、アクティビティAからstartActivityForResult()を使用してアクティビティBを開始し、アクティビティAのonActivtyResult()をオーバーライドします。

今度はアクティビティBで、ボタンUpでfinish()を呼び出すだけです。これで、再びアクティビティAを作成せずに、アクティビティAのonActivityResult()を指示しました。

77
user370305

私はほとんど同じセットアップをしていて、同じ望まれない振る舞いをしていました。私の場合、これはうまくいきました。私のアプリのManifest.xmlのアクティビティAに次の属性を追加します。

Android:launchMode="singleTask"

詳しくは この記事 をご覧ください。

22
androidnewbie

昔の質問ですが、ここでは(/最も - 清潔で最高の)別の解決策があります。これは、I ディープリンクされたアクティビティB から ウィジェット まで、すべての前の答えがうまくいかなかったためです。

public void navigateUp() {
final Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {
    Log.v(logTag, "Recreate back stack");
        TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();
  } else {
    NavUtils.navigateUpTo(this, upIntent);
  }
}

[ https://stackoverflow.com/a/31350642/570168 ]

しかしまた見なさい: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-Android

17
Tobias

これを達成するためのより良い方法は2つのことを使うことです:

NavUtils.navigateUpFromSameTask(this);

これを機能させるには、マニフェストファイルにアクティビティAに親アクティビティBがあることを示す必要があります。親アクティビティには何も必要ありません。バージョン4以降では、追加の作業なしでNiceの戻る矢印が表示されます(これは小さなコードでもこれより下のバージョンでも実行できます。以下に示します)。このデータは、manifest-> applicationタブで設定できます。 GUIで(親アクティビティー名までスクロールして手で入れます)

サポートノード:

バージョン4より下のバージョンをサポートしたい場合は、メタデータも含める必要があります。アクティビティを右クリックし、add-> meta data、name = Android.support.PARENT_ACTIVITYおよびvalue = your.full.activity.nameを選択します。

下のバージョンでもNiceの矢印を取得するには

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

これをすべて動作させるにはサポートライブラリバージョン7が必要になりますが、それだけの価値があります。

7
donald

私のために働いたものは追加されました:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case Android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        finish();
    }

TheRelevantActivity.Javaに移動して、今それは予想通りに働いています

そして追加することを忘れないでください:

getSupportActionbar.setDisplayHomeAsUpEnabled(true);メソッドのonCreate()

5
Hammad Nasir

@ LorenCKの回答に追加、変更

NavUtils.navigateUpFromSameTask(this);

あなたの活動が他の活動から開始され、これが他のアプリによって開始されたタスクの一部になる可能性がある場合は、以下のコードに進んでください。

Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    TaskStackBuilder.create(this)
            .addNextIntentWithParentStack(upIntent)
            .startActivities();
} else {
    NavUtils.navigateUpTo(this, upIntent);
}

これにより新しいタスクが開始され、以下のMin SDKバージョン<= 15のようにマニフェストで定義できるアクティビティの親アクティビティが開始されます。

<meta-data
        Android:name="Android.support.PARENT_ACTIVITY"
        Android:value="com.example.app_name.A" />

15以上の場合はparentActivityNameを使用

4
Sourabh

私はAndroid:launchMode="singleTask"を試しましたが、助けにはなりませんでした。 Android:launchMode="singleInstance"を使って私のために働きました

4
Pnemonic

私は悪い親活動名でアンドロイド5.0を使用して同様の問題を抱えていた

<activity
        Android:name=".DisplayMessageActivity"
        Android:label="@string/title_activity_display_message"
        Android:parentActivityName=".MainActivity" >
        <meta-data
            Android:name="Android.support.PARENT_ACTIVITY"
            Android:value="com.example.myfirstapp.MainActivity" />
    </activity>

私は親のアクティビティ名からcom.example.myfirstappを削除しました、そしてそれはきちんと働きました

3

Javaクラスの場合: -

    toolbar = (Toolbar) findViewById(R.id.apptool_bar);
    setSupportActionBar(toolbar);

    getSupportActionBar().setTitle("Snapdeal");

    getSupportActionBar().setHomeButtonEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

マニフェストでは: -

<activity
            Android:name=".SubActivity"
            Android:label="@string/title_activity_sub"
            Android:theme="@style/AppTheme" >
            <meta-data Android:name="Android.support.PARENT_ACTIVITY" Android:value=".MainActivity"></meta-data>
    </activity>

それはあなたを助けます

あなたの活動にattributeでマニフェスト情報を追加してください

Android:launchMode="singleTask"

私のためにうまくいっている

2
Pravesh Kumar

これを試して:

Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
intent = getIntent();   
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_b);
getActionBar().setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_b, menu);
return true;
}  


@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
    case Android.R.id.home:
    NavUtils.navigateUpTo(this,intent);
        return true;
}
return super.onOptionsItemSelected(item);
}
1
Luis Valadez
    @Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
    case Android.R.id.home:
        finish();
        return true;
}
return super.onOptionsItemSelected(item);

バックプレスのように

1
Dan Alboteanu

私のマニフェストに入り、アクティビティにAndroid:launchMode="singleTop"を追加することは私にとってのトリックでした。

ツールバーのUpボタンを押した後にAndroidに前のアクティビティの新しいインスタンスを作成させたくなかったので、これは特に私の問題を解決しました - ナビゲーション階層を上がったとき、前のアクティビティの既存のインスタンスを使いたかったのです。

参照: Android:launchMode

0
mumush

この解決策を試してみてください。NavUtils.navigateUpFromSameTask(this)を使用してください。子供の活動では: https://stackoverflow.com/a/49980835/7308789

0
Houssin Boulla