Android - botão Voltar na barra de título

111

Em muitos aplicativos (Calendário, Drive, Play Store), quando você toca em um botão e insere uma nova atividade, o ícone na barra de título se transforma em um botão Voltar, mas para o aplicativo que estou fazendo, isso não acontece. Como faço para que esse ícone o leve de volta à tela anterior?

Desenhou
fonte
Tente getSupportActionBar () no exemplo OnCreate aqui freakyjolly.com/how-to-add-back-arrow-in-android-activity
Code Spy

Respostas:

145

Existem duas etapas simples para criar um botão Voltar na barra de título:

Primeiro, torne o ícone do aplicativo clicável usando o seguinte código na atividade em cuja barra de título você deseja que tenha um botão Voltar:

ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);

Depois de adicionar o código acima, você verá uma seta para trás aparecer à esquerda do ícone do aplicativo.

insira a descrição da imagem aqui

Em segundo lugar, depois de fazer o acima, você ainda precisa criar um código que aproveitará o evento de clique. Para isso, lembre-se de que, ao clicar no ícone do aplicativo, um onOptionsItemSelectedmétodo é chamado. Portanto, para voltar à atividade anterior, adicione esse método à sua atividade e coloque o Intentcódigo nele que o levará de volta à atividade anterior. Por exemplo, digamos que a atividade para a qual você está tentando voltar seja chamada MyActivity. Para voltar a ele, escreva o método da seguinte maneira:

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), MyActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}

É isso aí!

(Na API de desenvolvedores do Android, recomenda-se mexer no manifesto e adicionar coisas como android:parentActivityName. Mas isso não parece funcionar para mim. O texto acima é mais simples e confiável.)

<meta-data
      android:name="android.support.PARENT_ACTIVITY"
      android:value=".MainActivity" />

E em sua atividade

getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Luke F.
fonte
23
Você explicou bem, mas se não estiver errado em onOptionItemSelected, você deve apenas chamar finish (); no seu caso, startActivityForResult iniciará a segunda atividade e quando você pressionar de volta a partir da segunda atividade, será lançado de volta à primeira atividade (onde você pressionou o ícone da barra de ação)
Yahya Arshad
8
Além disso, você deve fazer isso apenas se item.getItemId () for android.R.id.home
bitek
2
Como afirma o AS: "A invocação do método 'actionBar.setDisplayHomeAsUpEnabled (true)' pode produzir java.lang.NullPointerException"
statosdotcom
1
Aviso! Com uma ToolBar, a actionBar retorna null com travamento. Veja as respostas abaixo.
CoolMind
5
getActionBar () não funcionou para mim, o aplicativo simplesmente trava. getSupportActionBar () funcionou.
john ktejik,
60

use este código

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

depois disso escreva este código no onOptionsItemSelectedmétodo

  int id = item.getItemId();

     if (id==android.R.id.home) {
        finish();
    }
anupam sharma
fonte
1
getActionBar()me dá um valor nulo; Você sabe por quê?
msysmilu
3
porque não há ActionBar, por exemplo, com estilo <item name = "android: windowActionBar"> false </item> <item name = "android: windowNoTitle"> true </item>
Paul Verest
47

Eu finalmente consegui adicionar corretamente o botão Voltar à barra de ação / barra de ferramentas

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

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return true;
    }

    return super.onOptionsItemSelected(item);
}

public boolean onCreateOptionsMenu(Menu menu) {
    return true;
}
Lucy Fair
fonte
3
Esta é a única resposta que funciona para mim. Obrigado @LucyFair
Arda Çebi
2
Mesmo. Obrigado pela sua resposta.
Maria
Mesmo. Nenhuma das outras respostas funciona. Essa deveria ter sido a resposta aceita.
El Sushiboi
18

1.- Adicione a atividade a AndroidManifest.xml e certifique-se de fornecer os metadados:

<activity
    android:name="com.example.myfirstapp.DisplayMessageActivity"
    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.myfirstapp.MainActivity" />
</activity>

2.- Adicione o seguinte código ao método onCreate da atividade:

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

3.- Substitua o onOptionsItemSelected e use o método estático NavUtils.navigateUpFromSameTask () para navegar e lançar a pilha.

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

No entanto, o uso de navigateUpFromSameTask () é adequado apenas quando seu aplicativo é o proprietário da tarefa atual (ou seja, o usuário iniciou esta tarefa de seu aplicativo). Se isso não for verdade e sua atividade foi iniciada em uma tarefa que pertence a um aplicativo diferente, navegar para cima deve criar uma nova tarefa que pertence ao seu aplicativo, o que requer que você crie uma nova pilha de retorno.

astronauta
fonte
Obrigado por apresentar os NavUtils!
AntonSack
10

Se sua atividade estende a atividade

public class YourActivity extends Activity {

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

        getActionBar().setHomeButtonEnabled(true);

        [...]
    }

    [...]
}

Se sua ação estende AppCompatActivity

public class YourActivity extends AppCompatActivity {

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

            getSupportActionBar().setHomeButtonEnabled(true);

            [...]
        }

        [...]
    }

Nada mais a fazer, veja Adicionar ação

[OPCIONAL] Para definir explicitamente a atividade pai, modifique seu Manifest.xml assim:

<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.YourActivity "
        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.myfirstapp.MainActivity" />
    </activity>
</application>

Consulte Especificar a atividade pai

tot
fonte
1
Isso é exatamente o que eu estava procurando. Você salvou meu dia. Muito obrigado.
Tashi Dendup
6

Se sua atividade se estender, AppCompatActivityvocê precisará substituir o onSupportNavigateUp()método desta forma:

public class SecondActivity extends AppCompatActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_second);
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
       getSupportActionBar().setHomeButtonEnabled(true);
       getSupportActionBar().setDisplayHomeAsUpEnabled(true);
       ...
   }

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

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

Manipule sua lógica em seu onBackPressed()método e apenas chame esse método onSupportNavigateUp()para que o botão Voltar no telefone e a seta na barra de ferramentas façam a mesma coisa.

Ruzin
fonte
6

em primeiro lugar, na Função onCreate, adicione a seguinte linha

getSupportActionBar().setDisplayHomeAsUpEnabled(true);

e, em seguida, adicione a seguinte função no código:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                finish();
                return true;
        }

        return super.onOptionsItemSelected(item);
    }
M Anees
fonte
6

Primeiro você precisa escrever estes códigos

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

Em seguida, adicione esta linha no manifesto

 <activity android:name=".MainActivity"
            android:parentActivityName=".PreviousActivity"></activity>

Acho que vai funcionar

Shahriar Ahmad
fonte
5

Se você estiver usando a nova biblioteca de suporte para 5.1 no Android Studio, você pode usá-la em sua AppCompatActivity

 ActionBar actionBar = getSupportActionBar();
 actionBar.setHomeButtonEnabled(true);
 actionBar.setDisplayHomeAsUpEnabled(true);
 actionBar.setHomeAsUpIndicator(R.mipmap.ic_arrow_back_white_24dp);
 actionBar.setDisplayShowHomeEnabled(true);

Felicidades.

Ralphgabb
fonte
5

A maneira mais simples e prática recomendada conforme o Google explica aqui :

1. Adicione um pai para a atividade do seu filho no AndroidManifest.xml:

<activity 
        android:name=".ChildActivity"
        android:parentActivityName=".ParentActivity" >
</activity>

2. Ative o botão Voltar em sua atividade infantil:

myActionOrActionSupportBar.setDisplayHomeAsUpEnabled(true);

Funcionou para mim, espero que funcione para você também.

luke8800gts
fonte
isso só é válido se a atividade puder ter apenas uma atividade pai. Esse é o meu caso. +1
MQoder
A etapa 2 não foi necessária no meu caso.
Thomio
5

Depois de um tempo de qualidade que encontrei, a opção de tema é o principal problema no meu código E a seguir está a maneira adequada de mostrar a barra de ferramentas para mim

No arquivo AndroidManifest, primeiro você deve alterar o estilo do tema

Theme.AppCompat.Light.DarkActionBar
to 
Theme.AppCompat.Light.NoActionBar

então, em seu xml de atividades, você precisa chamar sua própria barra de ferramentas, como

<androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary"
        android:id="@+id/toolbar"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:elevation="4dp"/>

E então esta barra de ferramentas deve ser chamada em seu arquivo Java por

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

E para a barra de ferramentas que mostra U deve verificar o nulo para evitar NullPointerException

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

Para atividades em casa, adicione este

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

        return super.onOptionsItemSelected(item);
    }

OU para sua atividade desejada voltar

public boolean onOptionsItemSelected(MenuItem item){
    Intent myIntent = new Intent(getApplicationContext(), YourActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
MST
fonte
3

Eu vi tantos complexos responderem, então este é o meu código. Trabalhando aqui. Você pode conseguir isso de duas maneiras.

1) Compatibilidade com Android Stardard

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NavUtils;

import android.view.MenuItem;
import android.view.View;

public class EditDiscoveryActivity extends AppCompatActivity {

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

        /*toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                finish();
            }
        });*/
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

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

}

2) Use um ícone personalizado

Se você quiser usar código em comentários, você só precisa adicionar este arquivo em drawable, chamado ic_arrow_white_24dp.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24.0"
    android:viewportHeight="24.0">
    <path
        android:fillColor="#ffffff"
        android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
    </vector>

Com este código.

toolbar.setNavigationIcon(R.drawable.ic_arrow_white_24dp);
            toolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    finish();
                }
            });

Espero que ajude algumas pessoas aqui!

Zhar
fonte
2

Versão leve sem usar ActionBarActivityque ainda tem os mesmos comportamentos aqui:

public class ToolbarConfigurer implements View.OnClickListener {
    private Activity activity;

    public ToolbarConfigurer(Activity activity, Toolbar toolbar, boolean displayHomeAsUpEnabled) {
        toolbar.setTitle((this.activity = activity).getTitle());
        if (!displayHomeAsUpEnabled) return;
        toolbar.setNavigationIcon(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
        toolbar.setNavigationOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        NavUtils.navigateUpFromSameTask(activity);
    }
}

Uso: Coloque new ToolbarConfigurer(this, (Toolbar) findViewById(R.id.my_awesome_toolbar), true);em onCreate.

Meu Deus
fonte
Isso se encaixa com o novo widget da barra de ferramentas que está incluído na biblioteca de suporte. Obrigado!!
Clocker
2

Você precisa adicionar o código mencionado abaixo no arquivo de manifesto. Pesquise a atividade na qual deseja adicionar a funcionalidade de seta para trás. Se você encontrar um, tudo bem ou crie a atividade

<activity android:name=".SearchActivity">

</activity>

Em seguida, adicione as três linhas de código a seguir no meio.

<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.raqib.instadate.MainActivity" />

E não se esqueça de adicionar este pedaço de código em onCreate (); método de sua atividade particular em que você precisa da seta para trás.

        Toolbar toolbar = (Toolbar) findViewById(R.id.searchToolbar);
    setSupportActionBar(toolbar);
    try{
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }catch(NullPointerException e){
       Log.e("SearchActivity Toolbar", "You have got a NULL POINTER EXCEPTION");
    }

Foi assim que resolvi o problema. Obrigado.

Muhammad Raqib
fonte
2

As outras respostas não mencionam que você também pode definir isso no XML do seu Toolbarwidget:

app:navigationIcon="?attr/homeAsUpIndicator"

Por exemplo:

<android.support.v7.widget.Toolbar
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:background="?attr/colorPrimary"
    app:navigationIcon="?attr/homeAsUpIndicator"
    app:popupTheme="@style/AppTheme.PopupOverlay"
    app:title="@string/title_activity_acoustic_progress" />
Michael Litvin
fonte
2

Tudo o que você precisa fazer em 2020:
(considerando que você deseja retornar à MainActivity)

protected void onCreate(Bundle savedInstanceState){
    ...
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

public boolean onOptionsItemSelected(MenuItem item) {
    Intent myIntent = new Intent(getApplicationContext(), MainActivity.class);
    startActivityForResult(myIntent, 0);
    return true;
}
Ahmed Abdullah
fonte
Isso é interessante, mas você está assumindo que queremos voltar para MainActivity. Como você redirecionaria para qualquer atividade anterior?
15h02
1

Isso também pode ser feito sem código, especificando uma atividade pai no manifesto do aplicativo. Se você quiser um botão Voltar na Atividade B que irá para a Atividade A, basta adicionar a Atividade A como pai da Atividade B no manifesto.

aby4reality
fonte
1

Para kotlin:

   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        onBackPressed();
        return true;
    }
Raluca Lucaci
fonte
1

Eu precisei misturar algumas respostas para obter a resposta certa para mim porque meu aplicativo tem 3 atividades que podem ir e voltar a qualquer momento. Atividade1> Atividade2> Atividade3. Quando eu estava fazendo algo na minha atividade3, o botão Voltar estava voltando corretamente para a Atividade2. No entanto, da Activity2, usando finish(), estava voltando para Activity3 e não Activity1. E estou estendendo AppCompatActivity. Então, minha solução foi:

public class Activity2 extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...

            getSupportActionBar().setHomeButtonEnabled(true);
        }
    }

em AndroidManifest.xml:

<activity android:name=".activities.Activity2"
           android:parentActivityName="com.example.appname.activities.Activity1">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.example.appname.activities.Activity1" />
        </activity>

e, finalmente, o botão de ação no meu menu (barra de ações):

public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            ...

            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;

        }

        return super.onOptionsItemSelected(item);

    }

Usar NavUtils.navigateUpFromSameTask(this);funcionou para mim, em vez de finish().

Gi Tavares
fonte
1

Apenas compartilhando algo que me ajudou e pode ser útil para outras pessoas. Embora a maioria das respostas aqui estejam corretas, usando o getActionBar().setDisplayHomeAsUpEnabled(true);, isso não funcionou para mim. O problema que tive é que estava tentando criar uma segunda Activity manualmente, mas há mais detalhes envolvidos.
O que realmente resolveu meu problema foi seguir o tutorial de desenvolvedores Android ( https://developer.android.com/training/basics/firstapp/starting-activity ) para criar uma segunda atividade usando as próprias ferramentas do Android Studio:

Create the second activity
1. In the Project window, right-click the app folder and select New > Activity > Empty Activity.
2. In the Configure Activity window, enter "DisplayMessageActivity" for Activity Name and click Finish (leave all other properties set to the defaults).
Android Studio automatically does three things:
- Creates the DisplayMessageActivity file.
- Creates the corresponding activity_display_message.xml layout file.
- Adds the required <activity> element in AndroidManifest.xml.
ofri cofri
fonte
0

Você também pode simplesmente colocar onBackPressed()seu ouvinte onClick. Isso faz com que seu botão funcione como os botões padrão "back / up" em aplicativos Android!

user3700215
fonte
0
Toolbar toolbar=findViewById(R.id.toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

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

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

Isso está funcionando para mim. Suponha que haja duas atividades (Activityone, Activitytwo)

Atividade interna dois usam este código

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

On Activityone

//when you need to go second activity
startActivity(new Intent(Activityone.this, Activitytwo.class));

Isso deve ser incluído na segunda atividade dentro do arquivo de manifesto

<activity android:name=".Activitytwo"
        android:parentActivityName=".Activityone"></activity>

E o resultado seria assim

insira a descrição da imagem aqui

Muhaiminur Rahman
fonte
0
  protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.YourxmlFileName);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

  public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id==android.R.id.home) {
            finish();
            return true;
        }
        return false;
    }
S.Adikaram
fonte