Come implementare il pulsante Indietro di ActionBar per Android?


137

Ho un'attività con una visualizzazione elenco. Quando l'utente fa clic sull'elemento, si apre l'elemento "visualizzatore":

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

Funziona bene, ma sulla barra delle azioni non viene attivata la freccia indietro accanto all'icona dell'app. Mi sto perdendo qualcosa?


64
getActionBar().setDisplayHomeAsUpEnabled(true);in onCreate e switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}in onOptionsItemSelected? entrambi in ServicesViewActivity
Selvin

7
Perché non come risposta scaffalature?
KarlKarlsom,

Risposte:


264

Selvin ha già pubblicato la risposta giusta. Ecco, la soluzione in un bel codice:

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 funzione NavUtils.navigateUpFromSameTask(this)richiede di definire l'attività principale nel file AndroidManifest.xml

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

Vedi qui per ulteriori letture.


1
Nella mia situazione stavo cercando un modo per non chiamare onCreate del genitore quando ritornava su di esso. Per fare questo, ho usato la tua implementazione, ma ho chiamato finish () invece di NavUtils.navigateUpFromSameTask (questo). finish () chiama il mio onStart invece di onCreate che era più ideale per me.
Jon,

L'impostazione dei metadati in manifest è una chiave per far funzionare il pulsante di navigazione
VSB

Usa in getActionBar().setDisplayHomeAsUpEnabled(true);caso di utilizzo delle librerie di supporto.
Abhinav Upadhyay,

Come si cambia la direzione del "pulire"? Per impostazione predefinita, l'implementazione di questa navigazione posteriore sposta lo schermo da destra a sinistra e sembra che stia caricando una nuova schermata. Tuttavia, voglio che pulisca da sinistra a destra, proprio come premere il tasto Indietro del dispositivo.
Stingray_

Ho ricevuto l'errore: Causato da: java.lang.NullPointerException: tentativo di invocare il metodo virtuale "void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean)" su un riferimento a oggetto null
Jones

166

Assicurati che il pulsante Home di ActionBar sia abilitato nell'attività:

Android, API 5+:

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

ActionBarSherlock e 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);
}

Esempio MainActivityche si estende 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);
        }
    }
}

In questo modo tutte le attività desiderate possono avere la contropressione.

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>

Esempio MainActivityche si estende 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);
    }
}

Funziona per me quando cambio getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); in per getActionBar (). setDisplayHomeAsUpEnabled (true); e aggiunto questi @SuppressLint ("NewApi") sul metodo onCreate all'interno e all'esterno Per REF: => developer.android.com/training/implementing-navigation/…
gnganpath

1
@ganpath Attenzione, l'utilizzo di getActionBar è per API 11+ .
Jared Burrows,

17

Per abilitare il pulsante Indietro di ActionBar è ovviamente necessario un ActionBar nella tua attività. Questo è impostato dal tema che stai utilizzando. Puoi impostare il tema della tua attività in AndroidManfiest.xml. Se stai usando ad esempio il @android:style/Theme.NoTitleBartema, non hai una ActionBar. In questo caso la chiamata a getActionBar()restituirà null. Quindi assicurati di avere prima un ActionBar.

Il prossimo passo è impostare l' android:parentActivityNameattività che si desidera navigare se si preme il pulsante Indietro. Anche questo dovrebbe essere fatto AndroidManifest.xml.

Ora puoi abilitare il pulsante Indietro nel onCreatemetodo della tua attività "figlio".

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

Ora dovresti implementare la logica per il pulsante Indietro. Basta semplicemente ignorare il onOptionsItemSelectedmetodo nella propria attività "figlio" e verificare l'id del pulsante Indietro che è android.R.id.home.

Ora puoi attivare il metodo NavUtils.navigateUpFromSameTask(this); MA se non hai specificato android:parentActivityNamein te AndroidManifest.xmlquesto si bloccherà la tua app.

A volte questo è quello che vuoi perché ti ricorda che hai dimenticato "qualcosa". Quindi, se vuoi impedirlo, puoi verificare se la tua attività ha un genitore usando il getParentActivityIntent()metodo. Se restituisce null, non è stato specificato il genitore.

In questo caso puoi attivare il onBackPressed()metodo che fa sostanzialmente lo stesso che se l'utente premesse il pulsante Indietro sul dispositivo. Una buona implementazione che non blocca mai la tua app sarebbe:

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

Si noti che l'animazione visualizzata dall'utente è diversa tra NavUtils.navigateUpFromSameTask(this);e onBackPressed().

Dipende da te quale strada prendi, ma ho trovato la soluzione utile, soprattutto se usi una classe base per tutte le tue attività.


10

File AndroidManifest:

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

aggiungi in DettagliAttività:

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

è lavoro:]


Sembra che questo sia il modo più semplice per me. Grazie
TuanDPH,



3

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

Per raggiungere questo obiettivo, ci sono semplicemente due passaggi,

Passaggio 1: vai su AndroidManifest.xml e nel aggiungi il parametro nel tag - android: parentActivityName = ". Home.HomeActivity"

esempio :

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

Passaggio 2: in ActivityDetail aggiungi l'azione per la pagina / attività precedente

esempio :

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

3

Nel metodo OnCreate aggiungi questo:

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

Quindi aggiungi questo metodo:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}

1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

nel onCreatedmetodo per le nuove API.


1

Se stai usando Toolbar, stavo affrontando lo stesso problema. Ho risolto seguendo questi due passaggi

  1. In AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. In SecondActivity, aggiungi questi ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

0

I seguenti passaggi sono sufficienti per il pulsante Indietro:

Passaggio 1: questo codice dovrebbe essere in 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>

Passaggio 2: non darai

finish();

nell'attività genitore durante l'avvio dell'attività figlio.

Passaggio 3: se è necessario tornare all'attività padre dall'attività figlio, fornire semplicemente questo codice per l'attività figlio.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));

0

Basandomi sulla risposta di Jared, ho dovuto abilitare e implementare il comportamento del pulsante Indietro della barra delle azioni in diverse attività e ho creato questa classe di supporto per ridurre la duplicazione del codice.

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

Utilizzo in un'attività:

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

    ActionBarHelper.enableBackButton(this);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.