Отобразить стрелку назад на панели инструментов


496

Я мигрируют из ActionBarк Toolbarв моем приложении. Но я не знаю, как отобразить и установить событие нажатия на Back Arrow, Toolbarкак я это делал Actionbar.

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

С ActionBar, я звоню mActionbar.setDisplayHomeAsUpEnabled(true). Но подобного метода не существует.

Кто-нибудь когда-нибудь сталкивался с такой ситуацией и как-то нашел способ ее решить?



Используйте пример getSupportActionBar () здесь freakyjolly.com/how-to-add-back-arrow-in-android-activity
Шпион кода

Ответы:


900

Если вы используете, ActionBarActivityто вы можете сказать Android использовать Toolbarкак ActionBar:

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

А потом звонит

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);

будет работать. Вы также можете использовать это во фрагментах, которые прикреплены к ActionBarActivitiesвам, вы можете использовать это так:

((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true);
((ActionBarActivity) getActivity()).getSupportActionBar().setDisplayShowHomeEnabled(true);

Если вы не используете ActionBarActivitiesили хотите, чтобы стрелка назад на Toolbarзначке не была указана как ваша, SupportActionBarвы можете использовать следующее:

mActionBar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_action_back));
mActionBar.setNavigationOnClickListener(new View.OnClickListener() {
   @Override
   public void onClick(View v) {
       //What to do on back clicked
   }
});

Если вы используете android.support.v7.widget.Toolbar, то вы должны добавить следующий код к вашему AppCompatActivity:

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

12
Googles официальная иконка
репозитория

70
Если вы используете последнюю версию appcompat-v7 (21.0.3 или выше), вы можете использовать R.drawable.abc_ic_ab_back_mtrl_am_alpha для рисования стрелок назад, которое включено в библиотеку поддержки.
Taeho Kim

23
Обратите внимание, что getResources (). GetDrawable (...) устарела. Вместо этого вы должны использовать ContextCompat.getDrawable (context, ...).
Квентин С.

7
Не работает, не может найти ни то, R.drawable.abc_ic_ab_back_mtrl_am_alphaни другое R.drawable.ic_action_back.
Энрике де Соуза

10
получить значок «назад» из библиотеки поддержки toolbar.setNavigationIcon(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_material);
Bolein95

215

Я вижу много ответов, но вот мой, который не упоминался ранее. Работает с API 8+.

public class DetailActivity extends AppCompatActivity

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

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

    // add back arrow to toolbar
    if (getSupportActionBar() != null){
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // handle arrow click here
    if (item.getItemId() == android.R.id.home) {
        finish(); // close this activity and return to preview activity (if there is any)
    }

    return super.onOptionsItemSelected(item);
}

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

20
Upvote для onOptionItemSelected()этого завершает то, что MrEngineer13 не покрыл в своем ответе.
Атул

2
Спасибо, это сработало для меня. Кажется, это лучше, чем использование прослушивателя кликов, меня не волнуют отдельные панели инструментов
Mike76

Как я могу изменить цвет стрелки?
Дмитрий

Мне не нужны строки под строкой комментариев "панели инструментов", работает хорошо.
Hack06

173

Есть много способов добиться этого, вот мой любимый:

Планировка:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:navigationIcon="?attr/homeAsUpIndicator" />

Деятельность:

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

    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // back button pressed
        }
    });

13
использование атрибута темы намного лучше, чем большинство других предложений в этом вопросе
Педро Лоурейро

3
вместо использования setNavigationOnClickListener()вы можете добавить case android.R.id.home:внутрь 'onOptionsItemSelected () `.
Евгений

1
case android.R.id.homeне работал для меня так что после поиска некоторое время ваш ответ сделал свое дело .. спасибо.
Диджей

Это наиболее аутентичное решение, особенно если вы хотите использовать значок возврата по умолчанию для системы Android.
Науман Аслам

использование toolbar.setNavigationOnClickListener {onBackPressed ()}
filthy_wizard

74

Вы можете использовать метод setNavigationIcon панели инструментов. Android Doc

mToolBar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);

mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        handleOnBackPress();
    }
});

1
Не могли бы вы добавить пояснения к вашему ответу? Ответы только для кода осуждаются на SO.
гудок

1
Обратите внимание, что метод setNavigationOnClickListener()был добавлен в API уровне 21 и выше
Али Mehrpour

3
R.drawable.abc_ic_ab_back_mtrl_am_alpha больше не поддерживается 23.2.0, вместо этого используйте принятый ответ.
Милан

25

Если вы не хотите создавать кастом Toolbar, вы можете сделать это

public class GalleryActivity extends AppCompatActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...  
        getSupportActionBar().setTitle("Select Image");
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

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

В тебе AndroidManifest.xml

<activity
    android:name=".GalleryActivity"
    android:theme="@style/Theme.AppCompat.Light">        
</activity>

Вы также можете поместить это android:theme="@style/Theme.AppCompat.Light"в <aplication>теге, для применять ко всем видам деятельности

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


2
Спасибо заif (item.getItemId() == android.R.id.home)
Адизбек Эргашев

22
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setNavigationIcon(R.drawable.back_arrow); // your drawable
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            onBackPressed(); // Implemented by activity
        }
    });

И для API 21+ android:navigationIcon

<android.support.v7.widget.Toolbar
    android:navigationIcon="@drawable/back_arrow"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"/>

Должен быть принятый ответ.
Антон Малышев

17

Я использовал этот метод из документации разработчика Google :

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

Если вы получите исключение нулевого указателя, это может зависеть от темы. Попробуйте использовать другую тему в манифесте или используйте это альтернативно:

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

Затем в манифесте, где я устанавливаю родительское действие для текущего действия:

<activity
        android:name="com.example.myapp.MyCurrentActivity"
        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.myapp.MyMainActivity" />
</activity>

Я надеюсь, что это поможет вам!


1
Ссылка Google Docs и getSupportActionBar()работал. Спасибо!
Рик

15

Если вы были с помощью AppCompatActivityи пошли по пути он не используется, потому что вы хотите , чтобы не получить автоматическое , ActionBarчто она обеспечивает, потому что вы хотите выделить Toolbar, из - за ваших потребностей Material Design и CoordinatorLayoutили AppBarLayout, то, считаю , что это:

Вы все еще можете использовать AppCompatActivity, вам не нужно прекращать использовать его только для того, чтобы вы могли использовать <android.support.v7.widget.Toolbar>в вашем XML. Просто отключите стиль панели действий следующим образом:

Во-первых, выведите стиль из одной из тем NoActionBar, которая вам нравится в вашей styles.xml, которую я использовал Theme.AppCompat.Light.NoActionBarследующим образом:

<style name="SuperCoolAppBarActivity" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/primary</item>

    <!-- colorPrimaryDark is used for the status bar -->
    <item name="colorPrimaryDark">@color/primary_dark</item>
    ...
    ...
</style>

В манифесте своего приложения выберите только что определенную тему дочернего стиля, например:

    <activity
        android:name=".activity.YourSuperCoolActivity"
        android:label="@string/super_cool"
        android:theme="@style/SuperCoolAppBarActivity">
    </activity>

В вашем Activity Xml, если панель инструментов определена так:

...
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        />
...

Затем, и это важная часть, вы устанавливаете для панели действий поддержки значение AppCompatActivity, которое вы расширяете, чтобы панель инструментов в xml стала панелью действий. Мне кажется, что это лучший способ, потому что вы можете просто делать множество вещей, которые позволяет ActionBar, например, меню, автоматический заголовок активности, обработку выбора элементов и т. Д., Не прибегая к добавлению пользовательских обработчиков кликов и т. Д.

В переопределении onCreate вашей активности выполните следующие действия:

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

    setSupportActionBar(toolbar);
    //Your toolbar is now an action bar and you can use it like you always do, for example:
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} 

8
MyActivity extends AppCompatActivity {

    private Toolbar toolbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        toolbar = (Toolbar) findViewById(R.id.my_toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(arrow -> onBackPressed());
    }

Вы можете использовать retrolambda.
Артемий

это то, что у меня есть, и это не работает. не могу понять это.
filthy_wizard

7

Простой и легкий способ показать кнопку назад на панели инструментов

Вставьте этот код в метод onCreate

 if (getSupportActionBar() != null){

            getSupportActionBar().setDisplayHomeAsUpEnabled(true);
            getSupportActionBar().setDisplayShowHomeEnabled(true);
        }

Вставьте этот метод переопределения вне метода onCreate

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if(item.getItemId()== android.R.id.home) {

        finish();
    }
    return super.onOptionsItemSelected(item);
}

7

В Котлине это было бы

private fun setupToolbar(){
    toolbar.title = getString(R.string.YOUR_TITLE)
    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayHomeAsUpEnabled(true)
    supportActionBar?.setDisplayShowHomeEnabled(true)
}

// don't forget click listener for back button
override fun onSupportNavigateUp(): Boolean {
    onBackPressed()
    return true
}


5

В AppCompatActivity, например , вы можете сделать

public class GrandStatActivity extends AppCompatActivity {

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

    @Override
    public void onResume() {
        super.onResume();

        // Display custom title
        ActionBar actionBar = this.getSupportActionBar();
        actionBar.setTitle(R.string.fragment_title_grandstats);

        // Display the back arrow
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    // Back arrow click event to go to the parent Activity
    @Override
    public boolean onSupportNavigateUp() {
        onBackPressed();
        return true;
    }

}

4

В вашем файле манифеста для действия, в которое вы хотите добавить кнопку возврата, мы будем использовать свойство android: parentActivityName

        <activity
        android:name=".WebActivity"
        android:screenOrientation="portrait"
        android:parentActivityName=".MainActivity"
        />

PS Этот атрибут был введен в API Level 16.


3

Это работало отлично

public class BackButton extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.chat_box);
        Toolbar chatbox_toolbar=(Toolbar)findViewById(R.id.chat_box_toolbar);
        chatbox_toolbar.setTitle("Demo Back Button");
        chatbox_toolbar.setTitleTextColor(getResources().getColor(R.color.white));
        setSupportActionBar(chatbox_toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        chatbox_toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //Define Back Button Function
            }
        });
    }
}

3

Сначала вам нужно инициализировать панель инструментов:

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

затем нажмите кнопку «Назад» на панели действий:

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);

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

2

Если вы хотите получить стрелку назад на панели инструментов, которая не установлена ​​в качестве SupportActionBar:

(Котлин)

val resId = getResIdFromAttribute(toolbar.context, android.R.attr.homeAsUpIndicator)
toolbarFilter.navigationIcon = ContextCompat.getDrawable(toolbar.context, resId)
toolbarFilter.setNavigationOnClickListener { fragmentManager?.popBackStack() }

чтобы получить разрешение от атрибутов:

@AnyRes
fun getResIdFromAttribute(context: Context, @AttrRes attr: Int): Int {
    if (attr == 0) return 0
    val typedValueAttr = TypedValue()
    context.theme.resolveAttribute(attr, typedValueAttr, true)
    return typedValueAttr.resourceId
}

1

Добавьте это в xml активности в папке макета:

<android.support.design.widget.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/AppTheme.AppBarOverlay">
    <android.support.v7.widget.Toolbar
        android:id="@+id/prod_toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>

Сделайте панель инструментов кликабельной, добавьте их в метод onCreate:

Toolbar toolbar = (Toolbar) findViewById(R.id.prod_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        finish();
    }
});

1

Возможно, более надежный способ получить значок «вверх» из вашей темы (если не использовать панель инструментов в качестве панели действий):

toolbar.navigationIcon = context.getDrawableFromAttribute(R.attr.homeAsUpIndicator)

Чтобы превратить атрибут темы в рисованный объект, я использовал функцию расширения:

fun Context.getDrawableFromAttribute(attributeId: Int): Drawable {
    val typedValue = TypedValue().also { theme.resolveAttribute(attributeId, it, true) }
    return resources.getDrawable(typedValue.resourceId, theme)
}

0

Если вы используете DrawerLayout с ActionBarDrawerToggle , то, чтобы показать кнопку « Назад» вместо кнопки « Меню» (и наоборот), вам нужно добавить этот код в свою активность:

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

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, toolbar, R.string.application_name, R.string.application_name);
    mDrawerLayout.addDrawerListener(mDrawerToggle);

    mDrawerToggle.setHomeAsUpIndicator(R.drawable.ic_arrow_back_white_32dp);
    mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            onBackPressed(); // Or you can perform some other action here when Back button is clicked.
        }
    });
    mDrawerToggle.syncState();
    // ...
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    if (mDrawerToggle.onOptionsItemSelected(item))
        return true;

    switch (item.getItemId()) {
        case android.R.id.home:
            onBackPressed();
            return true;
        // ...
    }

    return super.onOptionsItemSelected(item);
}

public void showBackInToolbar(boolean isBack) {
    // Remove next line if you still want to be able to swipe to show drawer menu.
    mDrawerLayout.setDrawerLockMode(isBack ? DrawerLayout.LOCK_MODE_LOCKED_CLOSED : DrawerLayout.LOCK_MODE_UNLOCKED);
    mDrawerToggle.setDrawerIndicatorEnabled(!isBack);
    mDrawerToggle.syncState();
}

Поэтому, когда вам нужно показать кнопку « Назад» вместо кнопки « Меню» , вызовите showBackInToolbar (true) , а если вам нужна кнопка « Меню» , вызовите showBackInToolbar (false) .

Вы можете сгенерировать стрелку назад (ic_arrow_back_white_32dp) здесь , поиск arrow_back в разделе Clipart (используйте 32dp по умолчанию с отступом 8dp). Просто выберите нужный вам цвет.


0

Вы всегда можете добавить a Relative layoutили a Linear Layoutв свой файл Toolbarи разместить изображение в виде значка назад или значка закрытия в любом месте на панели инструментов, как вам нравится.

Например, я использовал относительное расположение на панели инструментов

 <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_top"
                android:layout_width="match_parent"
                android:layout_height="35dp"
                android:minHeight="?attr/actionBarSize"
                android:nextFocusDown="@id/netflixVideoGridView"
                app:layout_collapseMode="pin">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content">


                    <TextView

                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Myflix"
                        android:textAllCaps="true"
                        android:textSize="19sp"
                        android:textColor="@color/red"
                        android:textStyle="bold" />


                    <ImageView
                        android:id="@+id/closeMyFlix"
                        android:layout_alignParentRight="true"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical"
                        app:srcCompat="@drawable/vector_close" />


                </RelativeLayout>

            </android.support.v7.widget.Toolbar>

И это выглядит так:

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

Вы можете добавить прослушиватель щелчков на этом изображении из Activity или фрагмента следующим образом.

  closeMyFlix.setOnClickListener({
            Navigator.instance.showFireTV(  activity!!.supportFragmentManager)
        })

0

С Котлиным стало:

Xml:

<include
android:id="@+id/tbSignToolbar "
layout="@layout/toolbar_sign_up_in"/>

В вашей деятельности: -

setSupportActionBar(tbSignToolbar as Toolbar?)//tbSignToolbar :id of your toolbar 
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)

0

Если вы используете JetPack Navigation.

Вот макет для MainActivity

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
                                               xmlns:app="http://schemas.android.com/apk/res-auto"
                                               xmlns:tools="http://schemas.android.com/tools"
                                               android:layout_width="match_parent"
                                               android:layout_height="match_parent"
                                               tools:context=".MainActivity">

<androidx.appcompat.widget.Toolbar
        android:id="@+id/toolBar"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

</androidx.appcompat.widget.Toolbar>

<fragment
        android:id="@+id/my_nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:defaultNavHost="true"
        app:layout_constraintTop_toBottomOf="@id/toolBar"
        app:layout_constraintBottom_toTopOf="parent"
        app:navGraph="@navigation/nav_graph"/>

Настройте панель инструментов в своей деятельности, как показано ниже в onCreate () вашего класса Activity.

val navHostFragment = supportFragmentManager
        .findFragmentById(R.id.my_nav_host_fragment) as NavHostFragment? ?: return

val navController = navHostFragment.findNavController()
val toolBar = findViewById<Toolbar>(R.id.toolBar)
setSupportActionBar(toolBar) // To set toolBar as ActionBar
setupActionBarWithNavController(navController)

setupActionBarWithNavController (navController) Создает кнопку возврата на панели инструментов, если это необходимо, и обрабатывает функциональность backButton. Если вам нужно написать функциональность CustomBack, создайте callBack, как показано ниже для вашего фрагмента метода onCreate ()

val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
        // Handle the back button event
    }

Из документации: https://developer.android.com/guide/navigation/navigation-custom-back


0

Если вы используете androidx.appcompat.app.AppCompatActivityпросто использовать:

Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

Затем просто определите в Manifest.xmlродительской активности.

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

Вместо этого, если вы используете, Toolbarи вы хотите пользовательское поведение, просто используйте:

<androidx.appcompat.widget.Toolbar
    android:id="@+id/toolbar" 
    app:navigationIcon="?attr/homeAsUpIndicator"
    .../>

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

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //....
    }
});
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.