Exibir seta traseira na barra de ferramentas


496

Estou migrando de ActionBarpara Toolbarno meu aplicativo. Mas não sei como exibir e definir o evento de clique na Seta para trás Toolbarcomo eu fiz Actionbar.

insira a descrição da imagem aqui

Com ActionBar, eu ligo mActionbar.setDisplayHomeAsUpEnabled(true). Mas não existe um método semelhante como este.

Alguém já enfrentou essa situação e de alguma forma encontrou uma maneira de resolvê-la?



Use o exemplo getSupportActionBar () aqui freakyjolly.com/how-to-add-back-arrow-in-android-activity
Código Spy

Respostas:


900

Se você estiver usando um ActionBarActivity, então você pode dizer Android usar o Toolbarcomo o ActionBarassim:

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

E depois chama para

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

vai funcionar. Você também pode usar isso nos fragmentos anexados para ActionBarActivitiesusá-lo assim:

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

Se você não estiver usando ActionBarActivitiesou quiser colocar a seta para trás em uma Toolbarque não esteja definida como sua SupportActionBar, poderá usar o seguinte:

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

Se você estiver usando android.support.v7.widget.Toolbar, adicione o seguinte código ao seu AppCompatActivity:

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


70
Se você estiver usando a versão mais recente do appcompat-v7 (21.0.3 ou superior), poderá usar R.drawable.abc_ic_ab_back_mtrl_am_alpha para desenhar a seta para trás, incluída na biblioteca de suporte.
Taeho Kim

23
Observe que getResources (). GetDrawable (...) está obsoleto. Você deve usar ContextCompat.getDrawable (contexto, ...).
Quentin S.

7
Não funcionou, não pode encontrar nenhum dos R.drawable.abc_ic_ab_back_mtrl_am_alphadois R.drawable.ic_action_back.
Henrique de Sousa

10
para obter ícone "volta" da biblioteca de suporte toolbar.setNavigationIcon(android.support.v7.appcompat.R.drawable.abc_ic_ab_back_material);
Bolein95

215

Vejo muitas respostas, mas aqui está a minha, que não foi mencionada antes. Funciona a partir da 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
Isso só funciona se você definir a barra de ferramentas como a ActionBar. Não é para barras de ferramentas independentes.
Kuffs

20
onOptionItemSelected()Voto positivo para Isso completa o que MrEngineer13 não abordou em sua resposta.
Atul

2
Graças isso funcionou para mim. Parece ser melhor do que usar clique ouvinte, eu realmente não me importo sobre barras de ferramentas autônomas
Mike76

Como posso mudar a cor da seta?
Dmitry

Eu não precisava das linhas na linha de comentário "barra de ferramentas", funciona bem.
Hack06

173

Existem muitas maneiras de conseguir isso, eis o meu favorito:

Layout:

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

Atividade:

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

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

13
usando o atributo tema é muito melhor do que a maioria das outras sugestões neste pergunta
Pedro Loureiro

3
em vez de usar, setNavigationOnClickListener()você pode adicionar case android.R.id.home:dentro de 'onOptionsItemSelected () `.
Eugene

1
case android.R.id.homenão funcionou para mim. então, depois de pesquisar por um tempo, sua resposta foi bem-sucedida .. obrigado.
deejay

Esta é a solução mais autêntica, especialmente se você quiser usar o ícone de volta padrão do sistema Android.
Nauman Aslam

usando toolbar.setNavigationOnClickListener {onBackPressed ()} #
filthy_wizard

74

você pode usar o método setNavigationIcon da barra de ferramentas. Doc Android

mToolBar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);

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

1
Você poderia adicionar alguma explicação à sua resposta? As respostas somente de código são desaprovadas no SO.
Honk

1
Observe que o método setNavigationOnClickListener()foi adicionado no nível 21 da API e acima
Ali Mehrpour

3
R.drawable.abc_ic_ab_back_mtrl_am_alpha agora está no suporte 23.2.0, use a resposta aceita.
Milão

25

Se você não deseja criar um costume Toolbar, pode fazer assim

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

Em você AndroidManifest.xml

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

você também pode colocar isso android:theme="@style/Theme.AppCompat.Light"para <aplication>marcar, para aplicar a todas as atividades

insira a descrição da imagem aqui


2
Obrigado porif (item.getItemId() == android.R.id.home)
Adizbek Ergashev

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

E para API 21+ android:navigationIcon

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

Deve ser a resposta aceita.
Anton Malyshev

17

Eu usei esse método na documentação do desenvolvedor do Google :

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

Se você receber uma exceção de ponteiro nulo, isso poderá depender do tema. Tente usar um tema diferente no manifesto ou use isso como alternativa:

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

Em seguida, no manifesto, onde defino a atividade pai para a atividade atual:

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

Eu espero que isso te ajude!


1
O link do google docs e o getSupportActionBar()funcionado. Obrigado!
Rick Rick

15

Se você estava usando AppCompatActivitye seguiu o caminho de não usá-lo, porque queria não obter o automático ActionBarque ele fornece, porque deseja separar o Toolbar, por causa de suas necessidades de Design de Material e , CoordinatorLayoutou AppBarLayout, então, considere isso:

Você ainda pode usar o AppCompatActivity, não precisa parar de usá-lo apenas para poder usar um <android.support.v7.widget.Toolbar>no seu xml. Basta desativar o estilo da barra de ação da seguinte maneira:

Primeiro, derivar um estilo de um dos temas NoActionBar que você gosta no seu styles.xml, usei Theme.AppCompat.Light.NoActionBarassim:

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

No manifesto do seu aplicativo, escolha o tema de estilo filho que você acabou de definir, assim:

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

No seu XML de atividade, se a barra de ferramentas estiver definida assim:

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

Então, e esta é a parte importante, você define a barra de Ação de suporte como AppCompatActivity que está estendendo, para que a barra de ferramentas em seu xml se torne a barra de ação. Eu sinto que essa é uma maneira melhor, porque você pode simplesmente fazer as várias coisas que o ActionBar permite, como menus, título automático de atividade, manipulação de seleção de itens, etc., sem recorrer à adição de manipuladores de clique personalizados, etc.

Na substituição onCreate da sua atividade, faça o seguinte:

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

Você pode usar retrolambda.
31517 Artemiy

é isso que eu tenho e não está funcionando. não consigo descobrir.
filthy_wizard

7

Maneira simples e fácil de mostrar o botão Voltar na barra de ferramentas

Cole este código no método onCreate

 if (getSupportActionBar() != null){

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

Cole esse método de substituição fora do método onCreate

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

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

7

Em Kotlin seria

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

No AppCompatActivityexemplo, você pode fazer

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

No arquivo de manifesto da atividade em que você deseja adicionar um botão Voltar, usaremos a propriedade android: parentActivityName

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

PS Este atributo foi introduzido no nível 16 da API.


3

Isso funcionou perfeitamente

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

Primeiro, você precisa inicializar a barra de ferramentas:

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

depois chame o botão voltar da barra de ação:

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

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

2

Se você deseja obter a seta para trás em uma barra de ferramentas que não está definida como sua SupportActionBar:

(kotlin)

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

para obter res de atributos:

@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

Adicione isso ao xml da atividade na pasta de layout:

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

Torne a barra de ferramentas clicável, adicione-a ao método 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

Possivelmente, uma maneira mais confiável de obter o ícone para cima do seu tema (se não estiver usando a barra de ferramentas como barra de ação):

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

Para transformar o atributo theme em um drawable, usei uma função de extensão:

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

0

Se você estiver usando o DrawerLayout com o ActionBarDrawerToggle , para mostrar o botão Voltar em vez do botão Menu (e vice-versa), será necessário adicionar esse código à sua atividade:

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

Portanto, quando você precisar exibir o botão Voltar em vez do botão Menu , chame showBackInToolbar (true) e, se precisar do botão Menu , chame showBackInToolbar (false) .

Você pode gerar uma seta para trás (ic_arrow_back_white_32dp) por aqui , procure arrow_back na seção Clipart (use 32dp padrão com preenchimento 8dp). Basta selecionar a cor desejada.


0

Você sempre pode adicionar um Relative layoutou um Linear Layoutno seu Toolbare colocar uma visualização de imagem para o ícone voltar ou fechar o ícone em qualquer lugar da barra de ferramentas como desejar

Por exemplo, usei o layout relativo na minha barra de ferramentas

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

E fica assim:

insira a descrição da imagem aqui

Você pode adicionar um clique de ouvinte nessa exibição de imagem em Atividade ou fragmento como este.

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

0

Com Kotlin, tornou-se:

Xml:

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

Na sua atividade: -

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

0

Se você estiver usando o JetPack Navigation.

Aqui está o layout para 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"/>

Configure sua barra de ferramentas em sua atividade como abaixo em onCreate () da sua classe 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) Criará um botão voltar na barra de ferramentas, se necessário, e manipulará a funcionalidade backButton. Se você precisar escrever uma funcionalidade CustomBack, crie um callBack como abaixo no método fragment onCreate ()

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

Na documentação: https://developer.android.com/guide/navigation/navigation-custom-back


0

Se você estiver usando androidx.appcompat.app.AppCompatActivityapenas use:

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

Em seguida, basta definir na Manifest.xmlatividade pai.

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

Em vez disso, se você estiver usando um Toolbare quiser um comportamento personalizado, use:

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

e em sua atividade:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //....
    }
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.