Android - przycisk Wstecz na pasku tytułowym

112

W wielu aplikacjach (Kalendarz, Dysk, Sklep Play) po dotknięciu przycisku i wprowadzeniu nowej czynności ikona na pasku tytułu zamienia się w przycisk Wstecz, ale w przypadku tworzonej przeze mnie aplikacji tego nie robi. Jak sprawić, by ta ikona przenosiła Cię z powrotem do poprzedniego ekranu?

Rysował
źródło
Wypróbuj getSupportActionBar () w przykładzie OnCreate tutaj freakyjolly.com/how-to-add-back-arrow-in-android-activity
Code Spy

Odpowiedzi:

146

Istnieją dwa proste kroki, aby utworzyć przycisk Wstecz na pasku tytułu:

Najpierw spraw, aby ikona aplikacji była klikalna, używając następującego kodu w działaniu, w którym na pasku tytułu chcesz umieścić przycisk Wstecz:

ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

Po dodaniu powyższego kodu po lewej stronie ikony aplikacji pojawi się strzałka wstecz.

wprowadź opis obrazu tutaj

Po drugie, po wykonaniu powyższych czynności nadal musisz utworzyć kod, który wykorzysta zdarzenie kliknięcia. Aby to zrobić, pamiętaj, że po kliknięciu ikony aplikacji wywoływana onOptionsItemSelectedjest metoda. Aby więc wrócić do poprzedniej czynności, dodaj tę metodę do swojej aktywności i umieść Intentw niej kod, który spowoduje powrót do poprzedniej czynności. Na przykład, powiedzmy, że czynność, do której próbujesz wrócić, nazywa się MyActivity. Aby do niego wrócić, napisz metodę w następujący sposób:

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), MyActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}

Otóż ​​to!

(W interfejsie API dla programistów Androida zaleca się majstrowanie przy manifestie i dodawanie takich rzeczy, jak android:parentActivityName. Ale to nie działa dla mnie. Powyższe jest prostsze i bardziej niezawodne).

<meta-data
      android:name="android.support.PARENT_ACTIVITY"
      android:value=".MainActivity" />

I w Twojej Aktywności

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Łukasz F.
źródło
23
Dobrze wyjaśniłeś, ale jeśli nie jest źle w twoim onOptionItemSelected, powinieneś po prostu wywołać finish (); w twoim przypadku startActivityForResult uruchomi drugą czynność, a gdy wrócisz z drugiej czynności, zostaniesz przeniesiony z powrotem do pierwszej czynności (w której naciśnięto ikonę paska akcji)
Yahya Arshad
8
Co więcej, powinieneś to zrobić tylko wtedy, gdy item.getItemId () to android.R.id.home
bitek
2
Jak stwierdza AS: „Wywołanie metody 'actionBar.setDisplayHomeAsUpEnabled (true)' może generować java.lang.NullPointerException”
statosdotcom
1
Ostrzeżenie! Z ToolBarem actionBar zwraca wartość null z awarią. Zobacz odpowiedzi poniżej.
CoolMind
5
Funkcja getActionBar () nie działała, aplikacja po prostu ulega awarii. getSupportActionBar () zadziałało.
john ktejik
60

użyj tego kodu

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

po tym napisz ten kod w onOptionsItemSelectedmetodzie

  int id = item.getItemId();

     if (id==android.R.id.home) {
        finish();
    }
anupam sharma
źródło
1
getActionBar()daje mi zero; wiesz dlaczego?
msysmilu
3
ponieważ nie ma ActionBar, np. ze stylem <item name = "android: windowActionBar"> false </item> <item name = "android: windowNoTitle"> true </item>
Paul Verest
48

W końcu udało mi się poprawnie dodać przycisk Wstecz do paska akcji / paska narzędzi

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

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

    return super.onOptionsItemSelected(item);
}

public boolean onCreateOptionsMenu(Menu menu) {
    return true;
}
Lucy Fair
źródło
3
To jedyna odpowiedź, która mi pasuje. Dziękuję @LucyFair
Arda Çebi
2
Podobnie. Dziękuję za Twoją odpowiedź.
Maria
Podobnie. Żadna z pozostałych odpowiedzi nie działa. To powinna być zaakceptowana odpowiedź.
El Sushiboi
18

1. - Dodaj działanie do AndroidManifest.xml i upewnij się, że podajesz metadane:

<activity
    android:name="com.example.myfirstapp.DisplayMessageActivity"
    android:label="@string/title_activity_display_message"
    android:parentActivityName="com.example.myfirstapp.MainActivity" >
    <!-- Parent activity meta-data to support 4.0 and lower -->
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.myfirstapp.MainActivity" />
</activity>

2. - Dodaj następujący kod do metody onCreate działania:

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

3. - Zastąp onOptionsItemSelected i użyj statycznej metody NavUtils.navigateUpFromSameTask (), aby nawigować po wyrzucie stosu.

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

Jednak użycie metody navigateUpFromSameTask () jest odpowiednie tylko wtedy, gdy Twoja aplikacja jest właścicielem bieżącego zadania (czyli użytkownik rozpoczął to zadanie z Twojej aplikacji). Jeśli to nieprawda, a Twoja aktywność została rozpoczęta w zadaniu należącym do innej aplikacji, nawigacja w górę powinna utworzyć nowe zadanie należące do Twojej aplikacji, co wymaga utworzenia nowego stosu wstecznego.

spacebiker
źródło
Dziękujemy za wprowadzenie NavUtils!
AntonSack
10

Jeśli Twoja aktywność rozszerza Aktywność

public class YourActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xxx);

        getActionBar().setHomeButtonEnabled(true);

        [...]
    }

    [...]
}

Jeśli Twoja akcja rozszerza AppCompatActivity

public class YourActivity extends AppCompatActivity {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_xxx);

            getSupportActionBar().setHomeButtonEnabled(true);

            [...]
        }

        [...]
    }

Nie ma nic więcej do zrobienia, zobacz Dodawanie akcji

[OPCJONALNIE] Aby jawnie zdefiniować aktywność rodziców, zmodyfikuj plik Manifest.xml w ten sposób:

<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.YourActivity "
        android:label="@string/title_activity_display_message"
        android:parentActivityName="com.example.myfirstapp.MainActivity" >
        <!-- Parent activity meta-data to support 4.0 and lower -->
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.myfirstapp.MainActivity" />
    </activity>
</application>

Zobacz Określanie działania nadrzędnego

brzdąc
źródło
1
Właśnie tego szukałem. Uratowałeś mi dzień. Wielkie dzięki.
Tashi Dendup
6

Jeśli twoja aktywność się rozszerza AppCompatActivity, musisz zmienić onSupportNavigateUp()metodę w następujący sposób:

public class SecondActivity extends AppCompatActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_second);
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
       getSupportActionBar().setHomeButtonEnabled(true);
       getSupportActionBar().setDisplayHomeAsUpEnabled(true);
       ...
   }

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

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

Zajmij się logiką w swojej onBackPressed()metodzie i po prostu wywołaj tę metodę, onSupportNavigateUp()aby przycisk Wstecz w telefonie i strzałka na pasku narzędzi zrobiły to samo.

Ruzin
źródło
6

przede wszystkim w funkcji onCreate dodaj następujący wiersz

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

a następnie dodaj następującą funkcję w kodzie:

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

        return super.onOptionsItemSelected(item);
    }
M Anees
źródło
6

Najpierw musisz napisać te kody

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

Następnie dodaj tę linię w manifeście

 <activity android:name=".MainActivity"
            android:parentActivityName=".PreviousActivity"></activity>

Myślę, że to zadziała

Shahriar Ahmad
źródło
5

Jeśli używasz nowej biblioteki obsługi 5.1 w Android Studio, możesz zamiast tego użyć jej w AppCompatActivity

 ActionBar actionBar = getSupportActionBar();
 actionBar.setHomeButtonEnabled(true);
 actionBar.setDisplayHomeAsUpEnabled(true);
 actionBar.setHomeAsUpIndicator(R.mipmap.ic_arrow_back_white_24dp);
 actionBar.setDisplayShowHomeEnabled(true);

Twoje zdrowie.

ralphgabb
źródło
5

Najprostszy sposób i najlepsze praktyki, jak wyjaśnia Google tutaj :

1.Dodaj rodzica dla swojego dziecka Aktywność w AndroidManifest.xml:

<activity 
        android:name=".ChildActivity"
        android:parentActivityName=".ParentActivity" >
</activity>

2. aktywuj przycisk Wstecz w swoim dziecku Aktywność:

myActionOrActionSupportBar.setDisplayHomeAsUpEnabled(true);

Pracował dla mnie, mam nadzieję, że działa również dla Ciebie.

luke8800gts
źródło
jest to ważne tylko wtedy, gdy działanie może mieć tylko jedno działanie nadrzędne. Tak jest w przypadku mnie. +1
MQoder
Krok 2 nie był wymagany w moim przypadku.
Thomio
5

Po pewnym czasie, który znalazłem, opcja motywu jest głównym problemem w moim kodzie, a poniżej jest właściwy sposób pokazania paska narzędzi

W pliku AndroidManifest najpierw musisz zmienić styl motywu

Theme.AppCompat.Light.DarkActionBar
to 
Theme.AppCompat.Light.NoActionBar

następnie w pliku XML aktywności musisz wywołać swój własny pasek narzędzi, taki jak

<androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:elevation="4dp"/>

A następnie ten pasek narzędzi powinien zostać wywołany w pliku Java przez

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

W przypadku paska narzędzi wyświetlającego U należy sprawdzić wartość null, aby uniknąć wyjątku NullPointerException

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

W przypadku aktywności domowej z powrotem dodaj to

@Override
public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId()==android.R.id.home) {
            finish();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

LUB dla żądanej aktywności z powrotem

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), YourActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
MST
źródło
3

Widziałem odpowiedzi na tyle kompleksów, więc to jest mój kod. Pracuję tutaj. Możesz to osiągnąć na dwa sposoby.

1) Zgodność z Androidem Stardard

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NavUtils;

import android.view.MenuItem;
import android.view.View;

public class EditDiscoveryActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_edit_discovery);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        /*toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });*/
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

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

}

2) Użyj niestandardowej ikony

Jeśli chcesz używać kodu w komentarzach, wystarczy dodać ten plik do rysowania o nazwie ic_arrow_white_24dp.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#ffffff"
        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
    </vector>

Z tym kodem.

toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    finish();
                }
            });

Mam nadzieję, że pomoże to niektórym osobom tutaj!

Zhar
źródło
2

Wersja lekka bez użycia, ActionBarActivityktóra nadal ma tutaj te same bahaviors:

public class ToolbarConfigurer implements View.OnClickListener {
    private Activity activity;

    public ToolbarConfigurer(Activity activity, Toolbar toolbar, boolean displayHomeAsUpEnabled) {
        toolbar.setTitle((this.activity = activity).getTitle());
        if (!displayHomeAsUpEnabled) return;
        toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        toolbar.setNavigationOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        NavUtils.navigateUpFromSameTask(activity);
    }
}

Sposób użycia: Umieścić new ToolbarConfigurer(this, (Toolbar) findViewById(R.id.my_awesome_toolbar), true);w onCreate.

Mój Boże
źródło
Pasuje to do nowego widżetu paska narzędzi, który jest zawarty w bibliotece pomocy technicznej. Dzięki!!
Clocker
2

Musisz dodać poniższy kod w pliku manifestu. Wyszukaj działanie, do którego chcesz dodać funkcję strzałki wstecz. Jeśli znajdziesz ten, dobrze lub utwórz działanie

<activity android:name=".SearchActivity">

</activity>

Następnie dodaj następujące trzy wiersze kodu pomiędzy.

<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.raqib.instadate.MainActivity" />

I nie zapomnij dodać tego fragmentu kodu w onCreate (); metoda Twojej konkretnej aktywności, w której potrzebujesz strzałki wstecz.

        Toolbar toolbar = (Toolbar) findViewById(R.id.searchToolbar);
    setSupportActionBar(toolbar);
    try{
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }catch(NullPointerException e){
       Log.e("SearchActivity Toolbar", "You have got a NULL POINTER EXCEPTION");
    }

W ten sposób rozwiązałem problem. Dzięki.

Muhammad Raqib
źródło
2

Inne odpowiedzi nie wspominają, że możesz również ustawić to w XML swojego Toolbarwidżetu:

app:navigationIcon="?attr/homeAsUpIndicator"

Na przykład:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:title="@string/title_activity_acoustic_progress" />
Michael Litvin
źródło
2

Wszystko, co musisz zrobić w 2020 roku:
(biorąc pod uwagę, że chcesz wrócić do głównej aktywności)

protected void onCreate(Bundle savedInstanceState){
    ...
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

public boolean onOptionsItemSelected(MenuItem item) {
    Intent myIntent = new Intent(getApplicationContext(), MainActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
Ahmed Abdullah
źródło
To interesujące, ale zakładasz, że chcemy wrócić do MainActivity. Jak przekierowałbyś do poprzedniej aktywności?
mayid
1

Można to również zrobić bez kodu, określając działanie nadrzędne w manifeście aplikacji. Jeśli chcesz mieć przycisk Wstecz w działaniu B, który spowoduje przejście do działania A, po prostu dodaj działanie A jako element nadrzędny działania B w manifeście.

aby4reality
źródło
1

Kotlin:

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        onBackPressed();
        return true;
    }
Raluca Lucaci
źródło
1

Musiałem pomieszać niektóre odpowiedzi, aby uzyskać właściwą odpowiedź, ponieważ moja aplikacja ma 3 czynności, które mogą się powtarzać w dowolnym momencie. Aktywność1> Aktywność2> Aktywność3. Kiedy robiłem coś w swoim działaniu3, przycisk Wstecz prawidłowo cofał się do Działania2. Jednak z Activity2, używając finish(), było to kopiowanie do Activity3, a nie Activity1. I rozszerzam AppCompatActivity. Tak więc moje rozwiązanie brzmiało:

public class Activity2 extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...

            getSupportActionBar().setHomeButtonEnabled(true);
        }
    }

w AndroidManifest.xml:

<activity android:name=".activities.Activity2"
           android:parentActivityName="com.example.appname.activities.Activity1">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.appname.activities.Activity1" />
        </activity>

i na koniec przycisk akcji w moim menu (pasek akcji):

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            ...

            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;

        }

        return super.onOptionsItemSelected(item);

    }

Używanie NavUtils.navigateUpFromSameTask(this);zadziałało dla mnie zamiast finish().

Gi Tavares
źródło
1

Po prostu udostępniam coś, co mi pomogło i może być przydatne dla innych. Chociaż większość odpowiedzi tutaj jest poprawnych, to nie zadziałało, używając polecenia getActionBar().setDisplayHomeAsUpEnabled(true);. Problem polegał na tym, że próbowałem ręcznie utworzyć drugie działanie, ale jest więcej szczegółów.
To, co naprawdę rozwiązało mój problem, to skorzystanie z samouczka dla programistów Androida ( https://developer.android.com/training/basics/firstapp/starting-activity ), aby utworzyć drugie działanie przy użyciu własnych narzędzi Android Studio:

Create the second activity
1. In the Project window, right-click the app folder and select New > Activity > Empty Activity.
2. In the Configure Activity window, enter "DisplayMessageActivity" for Activity Name and click Finish (leave all other properties set to the defaults).
Android Studio automatically does three things:
- Creates the DisplayMessageActivity file.
- Creates the corresponding activity_display_message.xml layout file.
- Adds the required <activity> element in AndroidManifest.xml.
ofri cofri
źródło
0

Możesz także po prostu umieścić onBackPressed()odbiornik onClick. Powoduje to, że przycisk działa jak domyślny przycisk „Utwórz kopię zapasową” w aplikacjach na Androida!

user3700215
źródło
0
Toolbar toolbar=findViewById(R.id.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==android.R.id.home)
    finish();
return super.onOptionsItemSelected(item);
}
Abhay Agrawal
źródło
0

To działa dla mnie. Przypuśćmy, że istnieją dwie czynności (Activityone, Activitytwo)

Wewnątrz Activitytwo użyj tego kodu

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

Na Activityone

//when you need to go second activity
startActivity(new Intent(Activityone.this, Activitytwo.class));

Powinno to być uwzględnione w drugiej czynności w pliku manifestu

<activity android:name=".Activitytwo"
        android:parentActivityName=".Activityone"></activity>

Wynik byłby taki

wprowadź opis obrazu tutaj

Muhaiminur Rahman
źródło
0
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.YourxmlFileName);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

  public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id==android.R.id.home) {
            finish();
            return true;
        }
        return false;
    }
S.Adikaram
źródło