Как реализовать 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();
}

Источник: https://github.com/excilys/androidannotations

Я думаю 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));

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

  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);
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);
}
Другие вопросы по тегам