Как реализовать Android ActionBar кнопку назад?
У меня есть активность со списком. Когда пользователь щелкает элемент, открывается элемент "средство просмотра":
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);
}
});
Это работает нормально, но на панели действий стрелка назад рядом со значком приложения не активируется. Я что-то пропустил?
14 ответов
Селвин уже опубликовал правильный ответ, вот только решение в симпатичном коде;-)
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>
http://developer.android.com/design/patterns/navigation.html
Убедитесь, что ваша домашняя кнопка ActionBar включена в Activity:
Android, API 5+:
@Override
public void onBackPressed() {
...
super.onBackPressed();
}
ActionBarSherlock и App-Compat, API 7+:
@Override
public void onCreate(Bundle savedInstanceState) {
...
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Android, API 11+:
@Override
public void onCreate(Bundle savedInstanceState) {
...
getActionBar().setDisplayHomeAsUpEnabled(true);
}
пример MainActivity
это расширяет ActionBarActivity
:
public class MainActivity extends ActionBarActivity {
@Override
public void onCreate(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(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);
}
}
Чтобы включить кнопку возврата ActionBar, вам, очевидно, нужен ActionBar в вашей активности. Это устанавливается темой, которую вы используете. Вы можете установить тему для вашей Активности в AndroidManfiest.xml
, Если вы используете, например, @android:style/Theme.NoTitleBar
тема, у вас нет ActionBar. В этом случае вызов getActionBar()
вернет ноль. Поэтому сначала убедитесь, что у вас есть панель действий.
Следующим шагом является установка android:parentActivityName
к деятельности, которую вы хотите перейти, если вы нажмете кнопку назад. Это должно быть сделано в AndroidManfiest.xml
тоже.
Теперь вы можете включить кнопку назад в onCreate
метод вашей "детской" деятельности.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
}
Теперь вы должны реализовать логику для кнопки назад. Вы просто отменяете onOptionsItemSelected
метод в вашей "детской" деятельности и проверьте идентификатор кнопки "назад", которая android.R.id.home
,
Теперь вы можете запустить метод NavUtils.navigateUpFromSameTask(this);
НО, если вы не указали android:parentActivityName
в тебе AndroidManfiest.xml
это приведет к краху вашего приложения.
Иногда это то, что вы хотите, потому что это напоминает вам о том, что вы забыли "что-то", но если вы хотите предотвратить это, вы можете проверить, есть ли в вашей активности родитель, используя getParentActivityIntent()
метод. Если это возвращает нуль, вы не указали родителя.
В этом случае вы можете уволить 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()
,
От вас зависит, по какому пути вы идете, но я нашел решение полезным, особенно если вы используете базовый класс для всех ваших действий.
В методе OnCreate добавьте это:
if (getSupportActionBar() != null)
{
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
Затем добавьте этот метод:
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
Файл 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);
}
это работает:]
Аннотации Android:
@OptionsItem(android.R.id.home)
void homeSelected() {
onBackPressed();
}
Я думаю onSupportNavigateUp()
это самый простой и лучший способ сделать это
проверьте код в этой ссылке Нажмите здесь для полного кода
/questions/38545545/otobrazit-knopku-vozvrata-na-paneli-dejstvij/38545567#38545567
Чтобы достичь этого, есть просто два шага,
Шаг 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);}
}
Другой вариант - установить parentActivityName вторичного действия в MainActifity в файле манифеста приложения.
<activity
android:name=".ServiceViewActivity"
android:parentActivityName=".MainActivity"/>
Следующих шагов достаточно, чтобы вернуться назад:
Шаг 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));
Если вы используете панель инструментов, я столкнулся с той же проблемой. Я решил, выполнив эти два шага
- В AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
- В SecondActivity добавьте эти...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
в onCreated
метод для нового API.
Я пробовал это сам, и одна вещь, которая у меня сработала:
when(item.itemId) {
R.id.action_signup -> signup() //other menu item
android.R.id.home -> viewRoot.findNavController().navigateUp() //back
}
return super.onOptionsItemSelected(item)
}
Я использую навигацию Jetpack, так что это вызов для получения NavController.
Основываясь на ответе Джареда, мне пришлось включить и реализовать поведение кнопки возврата на панели действий в нескольких действиях и создал этот вспомогательный класс, чтобы уменьшить дублирование кода.
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);
}