Jak zaimplementować przycisk Wstecz Android ActionBar?

137

Mam aktywność z widokiem listy. Gdy użytkownik kliknie element, otwiera się „przeglądarka” elementu:

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

Działa to dobrze, ale na pasku akcji strzałka wstecz obok ikony aplikacji nie jest aktywowana. Czy coś mi brakuje?

Joaolvcm
źródło
64
getActionBar().setDisplayHomeAsUpEnabled(true);w onCreate i switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}w onOptionsItemSelected? oba w ServicesViewActivity
Selvin
7
Dlaczego nie jako odpowiedź na półki?
KarlKarlsom

Odpowiedzi:

264

Selvin już umieścił właściwą odpowiedź. Tutaj rozwiązanie w ładnym kodzie:

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

Funkcja NavUtils.navigateUpFromSameTask(this)wymaga zdefiniowania działania nadrzędnego w pliku AndroidManifest.xml

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

Więcej informacji znajdziesz tutaj .

surffan
źródło
1
W mojej sytuacji szukałem sposobu, aby nie odwoływać się do Kreacji rodzica, kiedy do niej wracam. Aby to zrobić, użyłem Twojej implementacji, ale wywołałem finish () zamiast NavUtils.navigateUpFromSameTask (this). finish () wywołuje mój onStart zamiast onCreate, co było dla mnie bardziej idealne.
Jon
Ustawienie metadanych w manifeście jest kluczem do działania przycisku nawigacji
VSB,
Użyj, getActionBar().setDisplayHomeAsUpEnabled(true);jeśli korzystasz z bibliotek wsparcia.
Abhinav Upadhyay
Jak zmienić kierunek „wycierania”? Domyślnie wdrożenie tej nawigacji wstecznej przesuwa ekran od prawej do lewej i wygląda na to, że ładuje nowy ekran. Jednak chcę, aby wyczyścił się od lewej do prawej, tak jak naciśnięcie własnego klawisza wstecznego urządzenia.
płaszczka_
Wystąpił błąd: spowodowany przez: java.lang.NullPointerException: próba wywołania metody wirtualnej „void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean)” w odniesieniu do obiektu zerowego
Jones
166

Upewnij się, że przycisk HomeBar jest włączony w działaniu:

Android, API 5+:

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

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

Przykład, MainActivityktóry rozszerza 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);
        }
    }
}

W ten sposób wszystkie czynności, które chcesz, mogą mieć backpress.

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>

Przykład, MainActivityktóry rozszerza 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
źródło
Działa dla mnie, gdy zmieniam getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); w getActionBar (). setDisplayHomeAsUpEnabled (true); i dodaje te @SuppressLint ( "NewApi") w metodzie onCreate wewnątrz i outsideFor Ref => developer.android.com/training/implementing-navigation/...
gnganpath
1
@ganpath Ostrożnie, używanie getActionBar jest przeznaczone dla API 11+ .
Jared Burrows
17

Aby włączyć przycisk Wstecz ActionBar, potrzebujesz oczywiście ActionBar w swoim działaniu. Jest to ustalane przez temat, którego używasz. Możesz ustawić motyw swojej aktywności w AndroidManfiest.xml. Jeśli używasz np @android:style/Theme.NoTitleBar. Motywu, nie masz ActionBar. W tym przypadku wywołanie getActionBar()zwróci wartość null. Więc najpierw upewnij się, że masz ActionBar.

Następnym krokiem jest ustawienie android:parentActivityNameczynności, do której chcesz nawigować, naciskając przycisk Wstecz. Należy to zrobić AndroidManifest.xmlrównież.

Teraz możesz włączyć przycisk Wstecz w onCreatemetodzie aktywności „dziecka”.

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

Teraz powinieneś zaimplementować logikę dla przycisku Wstecz. Po prostu nadpisujesz onOptionsItemSelectedmetodę w swojej aktywności „podrzędnej” i sprawdzasz identyfikator przycisku Wstecz, którym jest android.R.id.home.

Teraz możesz uruchomić metodę, NavUtils.navigateUpFromSameTask(this); ALE jeśli nie określiłeś android:parentActivityNamew tobie, AndroidManifest.xmlspowoduje to awarię aplikacji.

Czasami tego właśnie chcesz, ponieważ przypomina ci to, że zapomniałeś „czegoś”. Jeśli więc chcesz temu zapobiec, możesz sprawdzić, czy Twoja aktywność ma rodzica stosującego tę getParentActivityIntent()metodę. Jeśli zwraca wartość null, nie określono rodzica.

W takim przypadku możesz uruchomić onBackPressed()metodę, która działa w zasadzie tak samo, jak gdyby użytkownik nacisnął przycisk Wstecz na urządzeniu. Dobra implementacja, która nigdy nie powoduje awarii Twojej aplikacji, to:

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

Zwróć uwagę, że animacja, którą widzi użytkownik, różni się między NavUtils.navigateUpFromSameTask(this);i onBackPressed().

To od Ciebie zależy, którą drogę wybierzesz, ale uważam, że rozwiązanie jest pomocne, zwłaszcza jeśli używasz klasy bazowej do wszystkich swoich działań.

dknaack
źródło
10

Plik AndroidManifest:

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

dodaj Szczegóły

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

to jest praca :]

Sågär Śåxëńá
źródło
Wydaje mi się, że to dla mnie najłatwiejszy sposób. Dziękuję
TuanDPH
4

Myślę, że onSupportNavigateUp()jest to najprostszy i najlepszy sposób

sprawdź kod w tym linku Kliknij tutaj, aby uzyskać pełny kod

Inzimam Tariq IT
źródło
1
Wspaniały! Pracuje dla mnie. Dzięki!
morja
3

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

Aby to osiągnąć, wystarczy wykonać dwa kroki:

Krok 1: Przejdź do AndroidManifest.xml i dodaj parametr w tagu - android: parentActivityName = ". Home.HomeActivity"

przykład:

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

Krok 2: w ActivityDetail dodaj akcję dla poprzedniej strony / czynności

przykład:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Vivek Hande
źródło
3

W metodzie OnCreate dodaj to:

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

Następnie dodaj tę metodę:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Marco Concas
źródło
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

w onCreatedmetodzie dla nowego apis.

Kartik Garasia
źródło
1

Jeśli używasz paska narzędzi Toolbar, miałem ten sam problem. Rozwiązałem, wykonując te dwa kroki

  1. W pliku AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. W SecondActivity dodaj te ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
user2823506
źródło
0

Poniższe kroki wystarczą, aby cofnąć przycisk:

Krok 1: ten kod powinien znajdować się w pliku 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>

Krok 2: Nie poddasz się

finish();

w Aktywności rodzica podczas rozpoczynania Aktywności dziecka.

Krok 3: Jeśli chcesz wrócić do Aktywności rodzicielskiej z Aktywności dziecka, po prostu podaj ten kod Aktywności dziecka.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Kumar VL
źródło
0

Opierając się na odpowiedzi Jareda, musiałem włączyć i zaimplementować zachowanie przycisku cofania paska akcji w kilku działaniach i utworzyłem tę klasę pomocniczą, aby zmniejszyć powielanie kodu.

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

Wykorzystanie w działaniu:

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

    ActionBarHelper.enableBackButton(this);
}
datchung
źródło