Android - кнопка "Назад" в строке заголовка.

112

Во многих приложениях (Календарь, Диск, Play Store), когда вы нажимаете кнопку и вводите новое действие, значок в строке заголовка превращается в кнопку возврата, но для приложения, которое я создаю, этого не происходит. Как мне заставить этот значок вернуться на предыдущий экран?

Нарисовался
источник
Попробуйте getSupportActionBar () в примере OnCreate здесь freakyjolly.com/how-to-add-back-arrow-in-android-activity
Code Spy

Ответы:

146

Чтобы создать кнопку возврата в строке заголовка, нужно выполнить два простых шага:

Сначала сделайте значок приложения интерактивным, используя следующий код в действии, в строке заголовка которого вы хотите иметь кнопку возврата:

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

После того, как вы добавите приведенный выше код, вы увидите стрелку назад слева от значка приложения.

введите описание изображения здесь

Во-вторых, после того, как вы сделаете это, вам все равно придется создать код, который будет использовать событие щелчка. Для этого имейте в виду, что когда вы действительно щелкаете значок приложения, onOptionsItemSelectedвызывается метод. Итак, чтобы вернуться к предыдущему действию, добавьте этот метод к своему действию и поместите Intentв него код, который вернет вас к предыдущему действию. Например, предположим, что действие, к которому вы пытаетесь вернуться, называется MyActivity. Чтобы вернуться к нему, напишите метод следующим образом:

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

Это оно!

(В API разработчиков Android он рекомендует возиться с манифестом и добавлять что-то вроде android:parentActivityName. Но это, похоже, не работает для меня. Вышесказанное проще и надежнее.)

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

И в вашей деятельности

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Люк Ф.
источник
23
Вы хорошо объяснили, но если ваш onOptionItemSelected не ошибается, вам следует просто вызвать finish (); в вашем случае startActivityForResult запустит второе действие, и когда вы вернетесь со второго действия, вы вернетесь к первому действию (где вы нажали значок панели действий)
Яхья Аршад
8
Более того, вы должны делать это, только если item.getItemId () - это android.R.id.home
bitek
2
Как утверждает AS: «Вызов метода 'actionBar.setDisplayHomeAsUpEnabled (true)' может привести к
возникновению исключения
1
Предупреждение! С помощью ToolBar actionBar возвращает null при сбое. См. Ответы ниже.
CoolMind
5
getActionBar () у меня не работал, приложение просто вылетает. getSupportActionBar () работал.
John Ktejik
60

используйте этот код

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

после этого напишите этот код в onOptionsItemSelectedметоде

  int id = item.getItemId();

     if (id==android.R.id.home) {
        finish();
    }
анупам шарма
источник
1
getActionBar()дает мне ноль; ты знаешь почему?
msysmilu
3
потому что нет ActionBar, например, со стилем <item name = "android: windowActionBar"> false </item> <item name = "android: windowNoTitle"> true </item>
Пол Верест
48

Наконец-то мне удалось правильно добавить кнопку возврата на панель действий / панель инструментов

@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;
}
Люси Фэйр
источник
3
Это единственный ответ, который мне подходит. Спасибо @LucyFair
Arda ebi
2
Тем же. Спасибо за ваш ответ.
Мария
Тем же. Ни один из других ответов не работает. Это должен был быть принятый ответ.
El Sushiboi,
18

1.- Добавьте активность в AndroidManifest.xml и убедитесь, что предоставили метаданные:

<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.- Добавьте следующий код в метод onCreate действия:

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

3.- Переопределите onOptionsItemSelected и используйте статический метод NavUtils.navigateUpFromSameTask () для навигации по стеку.

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

Однако использование navigateUpFromSameTask () подходит только в том случае, если ваше приложение является владельцем текущей задачи (то есть пользователь начал эту задачу из вашего приложения). Если это не так, и ваша деятельность была запущена в задаче, принадлежащей другому приложению, то при переходе вверх должна быть создана новая задача, принадлежащая вашему приложению, для чего необходимо создать новый задний стек.

космический байкер
источник
Спасибо за представление NavUtils!
AntonSack
10

Если ваша активность расширяет Activity

public class YourActivity extends Activity {

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

        getActionBar().setHomeButtonEnabled(true);

        [...]
    }

    [...]
}

Если ваше действие расширяет AppCompatActivity

public class YourActivity extends AppCompatActivity {

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

            getSupportActionBar().setHomeButtonEnabled(true);

            [...]
        }

        [...]
    }

Больше нечего делать, см. Действие Добавить

[НЕОБЯЗАТЕЛЬНО] Чтобы явно определить родительскую активность, измените файл Manifest.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.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>

См. Указание родительского действия

малыш
источник
1
Это именно то, что я искал. Ты спас мне день. Большое спасибо.
Таши Дендуп,
6

Если ваша активность расширяется, AppCompatActivityвам необходимо переопределить onSupportNavigateUp()метод следующим образом:

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

Обработайте свою логику в своем onBackPressed()методе и просто вызовите этот метод, onSupportNavigateUp()чтобы кнопка «Назад» на телефоне и стрелка на панели инструментов делали то же самое.

Рузин
источник
6

прежде всего в функции onCreate добавьте следующую строку

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

а затем добавьте в код следующую функцию:

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

        return super.onOptionsItemSelected(item);
    }
M Anees
источник
6

Сначала вам нужно написать эти коды

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

Затем добавьте эту строку в манифест

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

Я думаю это сработает

Шахриар Ахмад
источник
5

Если вы используете новую библиотеку поддержки 5.1 в студии Android, вы можете вместо этого использовать ее в своем AppCompatActivity

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

ура.

ralphgabb
источник
5

Самый простой способ и лучшая практика, как объясняет Google здесь :

1. Добавьте родительский элемент для вашего childActivity в AndroidManifest.xml:

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

2. активируйте кнопку возврата в вашем childActivity:

myActionOrActionSupportBar.setDisplayHomeAsUpEnabled(true);

Сработало у меня, надеюсь, у вас тоже.

luke8800gts
источник
это допустимо только в том случае, если у действия может быть только одно родительское действие. Так обстоит дело со мной. +1
MQoder
В моем случае шаг 2 не требовался.
Thomio
5

По прошествии некоторого времени, которое я нашел, основная проблема в моем коде - это вариант темы. Ниже приводится правильный способ показать мне панель инструментов.

В файле AndroidManifest сначала вам нужно изменить стиль темы

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

то в вашей деятельности xml вам нужно вызвать свою собственную панель инструментов, например

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

Затем эта панель инструментов должна быть вызвана в вашем файле Java с помощью

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

И для панели инструментов, показывающей U, следует проверить значение null, чтобы избежать NullPointerException

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

Для домашней активности добавьте это

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

        return super.onOptionsItemSelected(item);
    }

ИЛИ для желаемой деятельности назад

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), YourActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
MST
источник
3

Я видел столько сложных ответов, так что это мой код. Здесь работают. Вы можете добиться этого двумя способами.

1) Совместимость с Android 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) Используйте собственный значок

Если вы хотите использовать код в комментариях, вам просто нужно добавить этот файл в файл с именем 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>

С этим кодом.

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

Надеюсь, это поможет некоторым людям здесь!

Жар
источник
2

Облегченная версия без использования, ActionBarActivityкоторая по-прежнему имеет те же действия:

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

Использование: Поместите new ToolbarConfigurer(this, (Toolbar) findViewById(R.id.my_awesome_toolbar), true);в onCreate.

О Господи
источник
Это соответствует новому виджету Панели инструментов, который включен в библиотеку поддержки. Спасибо!!
Clocker
2

Вам необходимо добавить указанный ниже код в файл манифеста. Найдите действие, в которое вы хотите добавить функцию стрелки назад. Если вы найдете тот, то штраф или создайте действие

<activity android:name=".SearchActivity">

</activity>

Затем добавьте между ними следующие три строки кода.

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

И не забудьте добавить этот фрагмент кода в onCreate (); метод вашей конкретной деятельности, в котором вам нужна стрелка назад.

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

Вот как я решил проблему. Спасибо.

Мухаммад Ракиб
источник
2

В других ответах не упоминается, что вы также можете установить это в XML своего Toolbarвиджета:

app:navigationIcon="?attr/homeAsUpIndicator"

Например:

<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" />
Михаил Литвин
источник
2

Все, что вам нужно сделать в 2020 году:
(учитывая, что вы хотите вернуться в MainActivity)

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;
}
Ахмед Абдулла
источник
Это интересно, но вы предполагаете, что мы хотим вернуться к MainActivity. Как бы вы перенаправили на любое предыдущее действие?
майид
1

Если вы используете ActionBar, вы захотите прочитать эту документацию http://developer.android.com/reference/android/app/ActionBar.html#setDisplayHomeAsUpEnabled(boolean)

Затем вам нужно перезаписать метод onOptionsItemSelected (MenuItem) и найти событие android.R.id.home, которое должно появиться. Тогда вы знаете, что пользователь нажал эту кнопку возврата на панели действий.

Пол Томпсон
источник
1

Это также можно сделать без кода, указав родительское действие в манифесте приложения. Если вам нужна кнопка возврата в Activity B, которая будет переходить к Activity A, просто добавьте Activity A в качестве родителя Activity B в манифесте.

aby4reality
источник
1

Для котлина:

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        onBackPressed();
        return true;
    }
Ралука Лукачи
источник
1

Мне нужно было смешать несколько ответов, чтобы получить правильный ответ, потому что в моем приложении есть 3 действия, которые можно вернуться и вернуться в любое время. Activity1> Activity2> Activity3. Когда я что-то делал в своем activity3, кнопка возврата правильно возвращалась к Activity2. Однако из Activity2, используя finish(), он поддерживал Activity3, а не Activity1. И я расширяю AppCompatActivity. Итак, мое решение было:

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

            getSupportActionBar().setHomeButtonEnabled(true);
        }
    }

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

и, наконец, кнопка действия в моем меню (панель действий):

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

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

        }

        return super.onOptionsItemSelected(item);

    }

У NavUtils.navigateUpFromSameTask(this);меня сработало using, а не finish().

Ги Таварес
источник
1

Просто поделитесь тем, что помогло мне и может быть полезно для других. Хотя большинство ответов здесь правильные, при использовании getActionBar().setDisplayHomeAsUpEnabled(true);это не сработало для меня. Проблема, с которой я столкнулся, заключалась в том, что я пытался создать вторую Activity вручную, но есть более подробные сведения.
Что действительно решило мою проблему, так это следование руководству разработчиков Android ( https://developer.android.com/training/basics/firstapp/starting-activity ) для создания второго Activity с использованием собственных инструментов 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.
офри кофри
источник
0

Вы также можете просто вставить onBackPressed()свой слушатель onClick. Это заставляет вашу кнопку работать как кнопки «резервное копирование / вверх» по умолчанию в приложениях Android!

user3700215
источник
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);
}
Абхай Агравал
источник
0

Это работает для меня .. Предположим, есть два действия (Activityone, Activitytwo)

Внутри Activitytwo используют этот код

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

На Activityone

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

Это должно быть включено во второе действие внутри файла манифеста

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

И результат будет таким

введите описание изображения здесь

Мухайминур Рахман
источник
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;
    }
С. Адикарам
источник