Comment implémenter le bouton de retour Android ActionBar?

137

J'ai une activité avec une vue de liste. Lorsque l'utilisateur clique sur l'élément, l'élément "visualiseur" s'ouvre:

List1.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) {

        Intent nextScreen = new Intent(context,ServicesViewActivity.class);
        String[] Service = (String[])List1.getItemAtPosition(arg2);

        //Sending data to another Activity
        nextScreen.putExtra("data", datainfo);
        startActivityForResult(nextScreen,0);
        overridePendingTransition(R.anim.right_enter, R.anim.left_exit);
    }
});

Cela fonctionne bien, mais dans la barre d'action, la flèche de retour à côté de l'icône de l'application ne s'active pas. Est-ce que je manque quelque chose?

Joaolvcm
la source
64
getActionBar().setDisplayHomeAsUpEnabled(true);dans onCreate et switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}dans onOptionsItemSelected? les deux dans ServicesViewActivity
Selvin
7
Pourquoi pas comme solution de mise en rayon?
KarlKarlsom

Réponses:

264

Selvin a déjà publié la bonne réponse. Ici, la solution en joli code:

public class ServicesViewActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // etc...
        getActionBar().setDisplayHomeAsUpEnabled(true);
    }

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

La fonction NavUtils.navigateUpFromSameTask(this)nécessite que vous définissiez l'activité parente dans le fichier AndroidManifest.xml

<activity android:name="com.example.ServicesViewActivity" >
    <meta-data
     android:name="android.support.PARENT_ACTIVITY"
     android:value="com.example.ParentActivity" />
</activity>

Voir ici pour plus de lecture.

surffan
la source
1
Dans ma situation je cherchais un moyen de ne pas appeler onCreate du parent en y retournant. Pour ce faire, j'ai utilisé votre implémentation, mais j'ai appelé finish () au lieu de NavUtils.navigateUpFromSameTask (this). finish () appelle mon onStart au lieu de onCreate, ce qui était plus idéal pour moi.
Jon
La définition de méta-données dans le manifeste est une clé pour faire fonctionner le bouton de navigation
VSB
Utilisez si getActionBar().setDisplayHomeAsUpEnabled(true);vous utilisez des bibliothèques de support.
Abhinav Upadhyay
Comment changez-vous la direction du "nettoyage"? Par défaut, la mise en œuvre de cette navigation arrière balaie l'écran de droite à gauche, et il semble que cela charge un nouvel écran. Cependant, je veux qu'il s'efface de gauche à droite, tout comme si vous appuyez sur la touche retour de l'appareil.
stingray_
J'ai eu l'erreur: Causé par: java.lang.NullPointerException: Tentative d'appeler la méthode virtuelle 'void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean)' sur une référence d'objet nul
Jones
166

Assurez-vous que votre bouton d'accueil ActionBar est activé dans l'activité:

Android, API 5+:

@Override
public void onBackPressed() {
     ...
     super.onBackPressed();
}

ActionBarSherlock et App-Compat, API 7+:

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

Android, API 11+:

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

Exemple MainActivityqui s'étend ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home: 
            // API 5+ solution
            onBackPressed();
            return true;

        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

De cette façon, toutes les activités que vous souhaitez peuvent avoir la contre-pression.

Android, API 16+:

http://developer.android.com/training/implementing-navigation/ancestral.html

AndroidManifest.xml:

<application ... >
    ...
    <!-- The main/home activity (it has no parent activity) -->
    <activity
        android:name="com.example.myfirstapp.MainActivity" ...>
        ...
    </activity>
    <!-- A child of the main activity -->
    <activity
        android:name="com.example.myfirstapp.DisplayMessageActivity"
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <!-- The meta-data element is needed for versions lower than 4.1 -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

Exemple MainActivityqui s'étend ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Back button
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    @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);
    }
}
Jared Burrows
la source
Cela fonctionne pour moi lorsque je change getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); dans pour getActionBar (). setDisplayHomeAsUpEnabled (true); et ajouté ces @SuppressLint ("NewApi") à la méthode onCreate à l'intérieur et à l'extérieurPour REF: => developer.android.com/training/implementing-navigation
...
1
@ganpath Attention, l'utilisation de getActionBar est pour l' API 11+ .
Jared Burrows
17

Pour activer le bouton de retour ActionBar, vous avez évidemment besoin d'une ActionBar dans votre activité. Ceci est défini par le thème que vous utilisez. Vous pouvez définir le thème de votre activité dans le AndroidManfiest.xml. Si vous utilisez par exemple le @android:style/Theme.NoTitleBarthème, vous n'avez pas d'ActionBar. Dans ce cas, l'appel à getActionBar()renverra null. Assurez-vous donc d'avoir d'abord une ActionBar.

L'étape suivante consiste à définir l' android:parentActivityNameactivité sur laquelle vous souhaitez naviguer si vous appuyez sur le bouton Retour. Cela devrait également être fait dans le AndroidManifest.xml.

Vous pouvez maintenant activer le bouton retour dans la onCreateméthode de votre activité "enfant".

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

Vous devez maintenant implémenter la logique du bouton de retour. Vous remplacez simplement la onOptionsItemSelectedméthode dans votre activité "enfant" et vérifiez l'identifiant du bouton de retour qui est android.R.id.home.

Maintenant , vous pouvez tirer la méthode NavUtils.navigateUpFromSameTask(this); MAIS si vous n'avez pas spécifié le android:parentActivityNameen vous AndroidManifest.xmlcela va planter votre application.

Parfois, c'est ce que vous voulez parce que cela vous rappelle que vous avez oublié «quelque chose». Donc, si vous voulez éviter cela, vous pouvez vérifier si votre activité a un parent utilisant la getParentActivityIntent()méthode. Si cela renvoie null, vous n'avez pas spécifié le parent.

Dans ce cas, vous pouvez déclencher la onBackPressed()méthode qui fait essentiellement la même chose que si l'utilisateur appuyait sur le bouton de retour de l'appareil. Une bonne implémentation qui ne plante jamais votre application serait:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            if (getParentActivityIntent() == null) {
                Log.i(TAG, "You have forgotten to specify the parentActivityName in the AndroidManifest!");
                onBackPressed();
            } else {
                NavUtils.navigateUpFromSameTask(this);
            }
            return true;
        default:
            return super.onOptionsItemSelected(item);
    }
}

Veuillez noter que l'animation que l'utilisateur voit est différente entre NavUtils.navigateUpFromSameTask(this);et onBackPressed().

C'est à vous de décider quelle route vous prenez, mais j'ai trouvé la solution utile, surtout si vous utilisez une classe de base pour toutes vos activités.

dknaack
la source
10

Fichier AndroidManifest:

    <activity android:name=".activity.DetailsActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="br.com.halyson.materialdesign.activity.HomeActivity" />
    </activity>

ajouter dans DetailsActivity:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

c'est du travail :]

Sågär Śåxëńá
la source
Il semble que ce soit le moyen le plus simple pour moi. Merci
TuanDPH le
4

Je pense que onSupportNavigateUp()c'est le moyen le plus simple et le meilleur de le faire

vérifiez le code dans ce lien Cliquez ici pour le code complet

Inzimam Tariq IT
la source
1
Génial! Travaille pour moi. Merci!
morja
3

https://stackoverflow.com/a/46903870/4489222

Pour y parvenir, il y a simplement deux étapes,

Étape 1: Accédez à AndroidManifest.xml et ajoutez le paramètre dans la balise - android: parentActivityName = ". Home.HomeActivity"

exemple :

 <activity
    android:name=".home.ActivityDetail"
    android:parentActivityName=".home.HomeActivity"
    android:screenOrientation="portrait" />

Étape 2: dans ActivityDetail, ajoutez votre action pour la page / activité précédente

exemple :

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Vivek Hande
la source
3

Dans la méthode OnCreate, ajoutez ceci:

if (getSupportActionBar() != null)
    {
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

Ajoutez ensuite cette méthode:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Marco Concas
la source
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

dans la onCreatedméthode pour les nouvelles apis.

Kartik Garasia
la source
1

Si vous utilisez la barre d'outils, j'étais confronté au même problème. J'ai résolu en suivant ces deux étapes

  1. Dans le fichier AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. Dans SecondActivity, ajoutez ces ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
user2823506
la source
0

Les étapes suivantes suffisent largement au bouton de retour:

Étape 1: ce code doit être dans Manifest.xml

<activity android:name=".activity.ChildActivity"
        android:parentActivityName=".activity.ParentActivity"
        android:screenOrientation="portrait">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activity.ParentActivity" /></activity>

Étape 2: vous ne donnerez pas

finish();

dans votre activité parentale lors du démarrage de l'activité enfant.

Étape 3: Si vous devez revenir à l'activité des parents depuis l'activité de l'enfant, donnez simplement ce code pour l'activité de l'enfant.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Kumar VL
la source
0

Sur la base de la réponse de Jared, j'ai dû activer et implémenter le comportement du bouton de retour de la barre d'action dans plusieurs activités et j'ai créé cette classe d'assistance pour réduire la duplication de code.

public final class ActionBarHelper {
    public static void enableBackButton(AppCompatActivity context) {
        if(context == null) return;

        ActionBar actionBar = context.getSupportActionBar();
        if (actionBar == null) return;

        actionBar.setDisplayHomeAsUpEnabled(true);
    }
}

Utilisation dans une activité:

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

    ActionBarHelper.enableBackButton(this);
}
datchung
la source