web-dev-qa-db-fra.com

Comment puis-je revenir correctement à une activité parent?

J'ai 2 activités (A et B) dans mon application Android et j'utilise l'intention de passer de l'activité A à l'activité B. L'utilisation de parent_activity est activée:

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

J'utilise aussi un thème qui fournit un bouton UP.

Ainsi, après avoir appelé l'activité BI, vous pouvez utiliser le bouton UP pour revenir à l'activité A. Le problème est que l'application semble appeler la fonction onCreate () - de l'activité A et ce n'est pas le comportement dont j'ai besoin. J'ai besoin que l'activité A ressemble à celle que j'avais avant que j'appelle l'activité B.

Y a-t-il un moyen d'y parvenir?

Merci d'avance

MODIFIER:

Je n'ai écrit aucun code pour démarrer l'activité B à partir de l'activité A. Je pense qu'elle est générée automatiquement par Eclipse.

La classe B ressemble à:

    @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);
}
172
ashiaka

Vous avez déclaré l'activité A avec la norme launchMode dans le manifeste Android. Selon la documentation , cela signifie que:

Le système crée toujours une nouvelle instance de l'activité dans la tâche cible et achemine l'intention vers celle-ci.

Par conséquent, le système est obligé de recréer l'activité A (c'est-à-dire en appelant onCreate) même si la pile de tâches est gérée correctement.

Pour résoudre ce problème, vous devez modifier le manifeste en ajoutant l'attribut suivant à la déclaration d'activité A:

Android:launchMode="singleTop"

Remarque: appeler finish() (comme suggéré précédemment comme solution) fonctionne uniquement lorsque vous êtes que vous êtes absolument certain que l'instance d'activité B que vous terminez vit sur une instance d'activité A. Dans des workflows plus complexes (par exemple, le lancement de l'activité B à partir d'une notification), cela pourrait ne pas être le cas et vous devez lancer correctement l’activité A à partir de B.

326
LorenzCK

Réponse mise à jour: Conception de la navigation vers le haut

Vous devez déclarer quelle activité est le parent approprié pour chaque activité. Cela permet au système de faciliter les modèles de navigation tels que Up, car il peut déterminer l'activité parent logique à partir du fichier manifeste.

Donc, pour cela, vous devez déclarer votre activité parent dans la balise Activity avec attribut

Android:parentActivityName

Comme,

<!-- 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>

Avec l’activité parent déclarée de cette façon, vous pouvez naviguer jusqu’au parent approprié comme ci-dessous,

@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);
}

Ainsi, lorsque vous appelez NavUtils.navigateUpFromSameTask(this); cette méthode, elle termine l'activité en cours et commence (ou reprend) l'activité parent appropriée. Si l'activité parent cible se trouve dans la pile arrière de la tâche, elle est avancée conformément à la définition de FLAG_ACTIVITY_CLEAR_TOP.

Et pour afficher le bouton Up, vous devez déclarer setDisplayHomeAsUpEnabled():

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

Ancienne réponse: (sans navigation vers le haut, navigation arrière par défaut)

Cela ne se produit que si vous démarrez à nouveau l'activité A à partir de l'activité B.

Utiliser startActivity().

Au lieu de cela, à partir de l'activité A, démarrez l'activité B en utilisant startActivityForResult() et remplacez onActivtyResult() dans l'activité A.

Maintenant, dans l'activité B, appelez simplement finish() sur le bouton Up. Alors maintenant, vous êtes dirigé vers la onActivityResult() de l'activité A sans créer de nouveau l'activité A ..

80
user370305

J'avais à peu près la même configuration menant au même comportement indésirable. Pour moi, cela a fonctionné: ajouter l'attribut suivant à une activité A dans le Manifest.xml de mon application:

Android:launchMode="singleTask"

Voir cet article pour plus d'explications.

22
androidnewbie

Bien qu’il s’agisse d’une vieille question, voici une autre solution (à mon humble avis, la meilleure et la meilleure) car toutes les réponses précédentes ne fonctionnaient pas pour moi puisque j’ai plongé dans l’activité B depuis un widget .

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 ]

Mais voir aussi: https://speakerdeck.com/jgilfelt/this-way-up-implementing-effective-navigation-on-Android

19
Tobias

Un meilleur moyen d'y parvenir est d'utiliser deux choses: appelez:

NavUtils.navigateUpFromSameTask(this);

Maintenant, pour que cela fonctionne, vous devez que votre fichier de manifeste indique que l'activité A a une activité parent B. L'activité parent n'a besoin de rien. Dans la version 4 et les versions ultérieures, vous obtiendrez une belle flèche de retour sans aucun effort supplémentaire (cela peut être fait aussi avec des versions plus basses avec un peu de code, je le mettrai ci-dessous). Vous pouvez définir ces données dans l'onglet manifest-> application dans l'interface graphique (faites défiler jusqu'au nom de l'activité parent et mettez-le à la main)

Noeud support:

si vous souhaitez prendre en charge la version inférieure à la version 4, vous devez également inclure des métadonnées. faites un clic droit sur l'activité, ajoutez-> métadonnées, nom = Android.support.PARENT_ACTIVITY et valeur = your.full.activity.name

pour obtenir la flèche de Nice dans les versions inférieures également:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

veuillez noter que vous aurez besoin de la bibliothèque d’assistance version 7 pour que tout fonctionne, mais cela en vaut la peine!

7
donald

Ce qui a fonctionné pour moi a été d'ajouter:

    @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 et maintenant il fonctionne comme prévu

et oui, n'oubliez pas d'ajouter:

getSupportActionbar.setDisplayHomeAsUpEnabled(true); dans la méthode onCreate()

5
Hammad Nasir

Ajouter à la réponse de @ LorenCK, changer

NavUtils.navigateUpFromSameTask(this);

au code ci-dessous si votre activité peut être lancée à partir d'une autre activité et que cela peut faire partie d'une tâche lancée par une autre application

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

Cela va démarrer une nouvelle tâche et démarrer l'activité parente de votre activité que vous pouvez définir dans Manifest comme ci-dessous pour la version Min du SDK <= 15

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

Ou en utilisant parentActivityName si sa> 15

4
Sourabh

J'ai essayé Android:launchMode="singleTask", mais ça n'a pas aidé. Travaillé pour moi avec Android:launchMode="singleInstance"

4
Pnemonic

J'ai eu un problème similaire avec Android 5.0 avec un nom d'activité parent incorrect.

<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>

J'ai supprimé le com.example.myfirstapp du nom de l'activité parent et cela a fonctionné correctement

3
Patrick Bergthold

Dans la classe Java: -

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

    getSupportActionBar().setTitle("Snapdeal");

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

En manifeste: -

<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>

Cela vous aidera

2

Ajoutez à votre manifeste d'activité des informations avec l'attribut

Android:launchMode="singleTask"

fonctionne bien pour moi

2
Pravesh Kumar

essaye ça:

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);

comme un dos presse

1
Dan Alboteanu

Entrer dans mon manifeste et ajouter Android:launchMode="singleTop" à l'activité a été décisif pour moi.

Cela a résolu mon problème, car je ne voulais pas que Android crée une nouvelle instance de l'activité précédente après avoir cliqué sur le bouton Up de la barre d'outils. Je souhaitais plutôt utiliser l'instance existante du fichier. activité antérieure lorsque je suis monté dans la hiérarchie de navigation.

Référence: Android: launchMode

0
mumush

Essayez cette solution en utilisant NavUtils.navigateUpFromSameTask (this); dans l'activité enfant: https://stackoverflow.com/a/49980835/7308789

0
Houssin Boulla