Como implementar o botão voltar do Android ActionBar?

137

Eu tenho uma atividade com uma listview. Quando o usuário clica no item, o item "visualizador" é aberto:

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

Isso funciona bem, mas na barra de ação a seta para trás ao lado do ícone do aplicativo não é ativada. Estou esquecendo de algo?

Joaolvcm
fonte
64
getActionBar().setDisplayHomeAsUpEnabled(true);em onCreate e switch (item.getItemId()) {case android.R.id.home: onBackPressed();break;}em onOptionsItemSelected? os dois em ServicesViewActivity
Selvin
7
Por que não como uma resposta prateleira?
#

Respostas:

263

Selvin já postou a resposta certa. Aqui, a solução em código bonito:

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

A função NavUtils.navigateUpFromSameTask(this)requer que você defina a atividade pai no arquivo AndroidManifest.xml

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

Veja aqui para ler mais.

surffan
fonte
1
Na minha situação, eu estava procurando uma maneira de não chamarCriar dos pais ao retornar a ele. Para fazer isso, usei sua implementação, mas chamei de finish () em vez de NavUtils.navigateUpFromSameTask (this). finish () chama meu onStart em vez de onCreate, o que era mais ideal para mim.
31416 Jon
Definir meta-dados no manifesto é a chave para fazer botão de navegação de trabalho
VSB
Use getActionBar().setDisplayHomeAsUpEnabled(true);caso você esteja usando bibliotecas de suporte.
Abhinav Upadhyay
Como você muda a direção da "limpeza"? Por padrão, a implementação dessa navegação traseira varre a tela da direita para a esquerda e parece que ela está carregando uma nova tela. No entanto, eu quero que ele apague da esquerda para a direita, assim como pressionar a tecla Voltar do próprio dispositivo.
Stingray_ #
Eu recebi o erro: Causado por: java.lang.NullPointerException: tentativa de invocar o método virtual 'void android.app.ActionBar.setDisplayHomeAsUpEnabled (boolean)' em uma referência de objeto nulo
Jones
165

Verifique se o botão inicial do ActionBar está ativado na atividade:

Android, API 5+:

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

ActionBarSherlock e App-Compat, API 7+:

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

Android, API 11+:

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

Exemplo MainActivityque se estende ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable 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);
        }
    }
}

Dessa forma, todas as atividades que você deseja podem ter a contrapressão.

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>

Exemplo MainActivityque se estende ActionBarActivity:

public class MainActivity extends ActionBarActivity {
    @Override
    public void onCreate(@Nullable 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);
    }
}
Jared Burrows
fonte
Está funcionando para mim quando altero getSupportActionBar (). SetDisplayHomeAsUpEnabled (true); em getActionBar (). setDisplayHomeAsUpEnabled (true); e adicionou estes @SuppressLint ("NewApi") no método onCreate dentro e foraPara REF: => developer.android.com/training/implementing-navigation/…
gnganpath 13/15
1
@ganpath Cuidado, usar getActionBar é para API 11+ .
Jared Burrows
17

Para ativar o botão Voltar da ActionBar, você obviamente precisa de uma ActionBar em sua Atividade. Isso é definido pelo tema que você está usando. Você pode definir o tema para sua atividade no AndroidManfiest.xml. Se você estiver usando, por exemplo, o @android:style/Theme.NoTitleBartema, você não possui uma ActionBar. Nesse caso, a chamada paragetActionBar() retornará nulo. Portanto, verifique se você tem um ActionBar primeiro.

O próximo passo é definir a android:parentActivityNameatividade que você deseja navegar se pressionar o botão Voltar. Isso deve ser feito noAndroidManifest.xml também.

Agora você pode ativar o botão Voltar no onCreatemétodo da sua atividade "filho".

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

Agora você deve implementar a lógica do botão voltar. Você simplesmente substitui o onOptionsItemSelectedmétodo em sua atividade "filho" e verifica o ID do botão Voltar, que é android.R.id.home.

Agora você pode disparar o método, NavUtils.navigateUpFromSameTask(this); mas se você não tiver especificado o que está android:parentActivityNameem você, AndroidManifest.xmlisso causará um travamento no aplicativo.

Às vezes, é isso que você quer, porque está lembrando que você esqueceu "algo". Portanto, se você deseja evitar isso, pode verificar se sua atividade tem um pai usando o getParentActivityIntent()método Se isso retornar nulo, você não especificou o pai.

Nesse caso, você pode acionar o onBackPressed()método que faz basicamente o mesmo, como se o usuário pressionasse o botão Voltar no dispositivo. Uma boa implementação que nunca trava seu aplicativo seria:

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

Observe que a animação que o usuário vê é diferente entre NavUtils.navigateUpFromSameTask(this);eonBackPressed() .

Depende de você que caminho você seguirá, mas achei a solução útil, especialmente se você usar uma classe base para todas as suas atividades.

dknaack
fonte
10

Arquivo AndroidManifest:

    <activity android:name=".activity.DetailsActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="br.com.halyson.materialdesign.activity.HomeActivity" />
    </activity>

adicionar detalhes

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);   
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

isso funciona :]

Sågär Śåxëńá
fonte
Parece que esta é a maneira mais fácil para mim. Obrigado
TuanDPH
4

Eu acho que onSupportNavigateUp()é a maneira mais simples e melhor de fazer isso

verifique o código neste link Clique aqui para obter o código completo

Inzimam Tariq IT
fonte
1
Ótimo! Funciona para mim. Obrigado!
morja
3

https://stackoverflow.com/a/46903870/4489222

Para conseguir isso, existem simplesmente duas etapas,

Etapa 1: Vá para AndroidManifest.xml e adicione o parâmetro na tag - android: parentActivityName = ". Home.HomeActivity"

exemplo:

 <activity
    android:name=".home.ActivityDetail"
    android:parentActivityName=".home.HomeActivity"
    android:screenOrientation="portrait" />

Etapa 2: em ActivityDetail, adicione sua ação para a página / atividade anterior

exemplo:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
   switch (item.getItemId()) {
      case android.R.id.home: 
          onBackPressed();
          return true;
   }
   return super.onOptionsItemSelected(item);}
}
Vivek Hande
fonte
3

No método OnCreate, adicione isso:

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

Em seguida, adicione este método:

@Override
public boolean onSupportNavigateUp() {
    onBackPressed();
    return true;
}
Marco Concas
fonte
1
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

no onCreatedmétodo para as novas APIs.

Kartik Garasia
fonte
1

Se você estiver usando a Barra de Ferramentas, eu estava enfrentando o mesmo problema. Eu resolvi seguindo estes dois passos

  1. No AndroidManifest.xml
<activity android:name=".activity.SecondActivity" android:parentActivityName=".activity.MainActivity"/>
  1. No SecondActivity, adicione estes ...
Toolbar toolbar = findViewById(R.id.second_toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
user2823506
fonte
0

As etapas a seguir são suficientes para voltar ao botão:

Etapa 1: esse código deve estar no 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>

Etapa 2: você não dará

finish();

na atividade dos pais ao iniciar a atividade infantil.

Etapa 3: se você precisar voltar para a Atividade pai a partir de Atividade infantil, basta fornecer este código para Atividade infantil.

startActivity(new Intent(ParentActivity.this, ChildActivity.class));
Kumar VL
fonte
0

Com base na resposta de Jared, tive que habilitar e implementar o comportamento do botão voltar da barra de ação em várias atividades e criei essa classe auxiliar para reduzir a duplicação de código.

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

Uso em uma atividade:

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

    ActionBarHelper.enableBackButton(this);
}
datchung
fonte