Как реализовать кнопку возврата Android ActionBar?

139

У меня есть активность со списком. Когда пользователь щелкает элемент, открывается элемент «просмотрщик»:

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

Это работает нормально, но на панели действий стрелка назад рядом со значком приложения не активируется. Я что-то упускаю?

Joaolvcm
источник
64
getActionBar().setDisplayHomeAsUpEnabled(true);в onCreate и switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}в onOptionsItemSelected? оба в ServicesViewActivity
Selvin
7
Почему не в качестве ответа стеллажи?
KarlKarlsom

Ответы:

269

Селвин уже опубликовал правильный ответ. Вот решение в красивом коде:

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

Функция NavUtils.navigateUpFromSameTask(this)требует, чтобы вы определяли родительскую активность в файле AndroidManifest.xml.

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

См. Здесь для дальнейшего чтения.

Surffan
источник
1
В моей ситуации я искал способ не вызывать onCreate родителя при возвращении к нему. Для этого я использовал вашу реализацию, но вызвал finish () вместо NavUtils.navigateUpFromSameTask (this). finish () вызывает мой onStart вместо onCreate, который был более идеальным для меня.
Джон
Установка метаданных в манифесте - ключ к работе кнопки навигации
VSB
Используйте, если getActionBar().setDisplayHomeAsUpEnabled(true);вы используете библиотеки поддержки.
Abhinav Upadhyay
Как изменить направление "вайпа"? По умолчанию при реализации этой обратной навигации экран перемещается справа налево, и похоже, что загружается новый экран. Однако я хочу, чтобы он протирался слева направо, как при нажатии собственной клавиши возврата на устройстве.
stingray_
Я получил ошибку: Вызвано: java.lang.NullPointerException: попытка вызвать виртуальный метод void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean) для ссылки на нулевой объект
Джонс,
168

Убедитесь, что кнопка «Домой» в ActionBar включена в Activity:

Android, API 5+:

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

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

Пример, MainActivityкоторый расширяется 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);
        }
    }
}

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

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>

Пример, MainActivityкоторый расширяется 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);
    }
}
Джаред Берроуз
источник
У меня работает, когда я меняю getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); в getActionBar (). setDisplayHomeAsUpEnabled (true); и добавил эти @SuppressLint ("NewApi") в метод onCreate внутри и снаружи. Для REF: => developer.android.com/training/implementing-navigation/…
gnganapath
1
@ganpath Осторожно, getActionBar используется для API 11+ .
Джаред Берроуз,
18

Чтобы включить кнопку возврата ActionBar, вам, очевидно, понадобится ActionBar в вашей Activity. Это устанавливается темой, которую вы используете. Вы можете установить тему для своей деятельности вAndroidManfiest.xml . Если вы используете, например, @android:style/Theme.NoTitleBarтему, у вас нет ActionBar. В этом случае вызов getActionBar()вернет null. Поэтому сначала убедитесь, что у вас есть ActionBar.

Следующим шагом является установка android:parentActivityName по которому вы хотите перемещаться, если вы нажмете кнопку «Назад». Это AndroidManifest.xmlтоже нужно сделать в .

Теперь вы можете включить кнопку "Назад" в onCreate методе вашего «дочернего» действия.

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

Теперь вам нужно реализовать логику кнопки возврата. Вы просто переопределяете onOptionsItemSelectedметод в своем «дочернем» действии и проверяете идентификатор кнопки возврата, которая есть android.R.id.home.

Теперь вы можете запустить метод, NavUtils.navigateUpFromSameTask(this); НО если вы не указали android:parentActivityNamein you, AndroidManifest.xmlэто приведет к сбою вашего приложения.

Иногда это то, чего вы хотите, потому что это напоминает вам, что вы «что-то забыли». Поэтому, если вы хотите предотвратить это, вы можете проверить, есть ли у вашей активности родительский объект, используя этот getParentActivityIntent()метод. Если это возвращает значение null, вы не указали родителя.

В этом случае вы можете запустить onBackPressed()метод, который в основном работает так же, как если бы пользователь нажал кнопку возврата на устройстве. Хорошая реализация, которая никогда не приведет к сбою вашего приложения, будет:

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

Обратите внимание, что анимация, которую видит пользователь, различается между NavUtils.navigateUpFromSameTask(this); и onBackPressed().

Какой путь выбрать, решать вам, но я нашел решение полезным, особенно если вы используете базовый класс для всех своих действий.

dknaack
источник
Благодарность! Работает отлично.
Вахид Назир,
10

Файл AndroidManifest:

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

добавить в DetailsActivity:

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

это работает :]

Sågär åxëñá
источник
Кажется, это самый простой способ для меня. Спасибо
TuanDPH
3

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

Для этого нужно всего два шага:

Шаг 1. Перейдите в AndroidManifest.xml и добавьте параметр в тег - android: parentActivityName = ". Home.HomeActivity"

пример :

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

Шаг 2: в ActivityDetail добавьте действие для предыдущей страницы / действия

пример :

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Вивек Ханде
источник
3

В методе OnCreate добавьте следующее:

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

Затем добавьте этот метод:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Марко Конкас
источник
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

в onCreatedметоде для нового API.

Картик Гарасия
источник
1

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

  1. В AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. В SecondActivity добавьте эти ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
user2823506
источник
0

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

Шаг 1. Этот код должен быть в 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>

Шаг 2: вы не отдадите

finish();

в родительском действии при запуске дочернего действия.

Шаг 3. Если вам нужно вернуться к родительской активности из дочерней активности, вы просто даете этот код для дочерней активности.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Кумар В.Л.
источник
0

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

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

Использование в деятельности:

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

    ActionBarHelper.enableBackButton(this);
}
Datchung
источник