Android – Implementando corretamente o botão voltar na ActionBar (Providing Up Navigation)

navigation up action bar

Todas as telas em seu aplicativo que não são a entrada principal para o seu aplicativo (a tela “home”) deve oferecer ao usuário uma maneira de navegar para a tela pai lógica na hierarquia do aplicativo pressionando o botão Up na Action Bar . Esta lição mostra como implementar adequadamente esse comportamento.

Os conceitos e princípios para a navegação acima são descritos em Designing Effective Navigation e em Navigation  guia de design. É muito importante ler esse conceito para aprender a forma correta da utilização do Navigation UP, tenha em mente que ele não é como o nosso botão de voltar do Sistema Operacional, o comportamento dele deve ser visto de outra maneira.

Resumindo, o botão up deve navegar entre as telas de forma hierárquica já o botão voltar em ordem cronológica inversa.

Exemplo:

Navegação entre telas e uso do Botão UP

Navegação entre telas e uso do Botão UP

Leia mais em: Navigation é um artigo muito bom que vai ajudar seu sistema ter uma excelente navegação.

Agora depois dessa introdução vamos colocar o botão para funcionar. Primeiramente vamos declarar no Manifest, em sua Activity, a ordem hierárquica da tela.

A partir do Android 4.1 (API nível 16), você pode declarar o pai lógico de cada atividade, especificando o android:parentActivityName  na <activity>

Se o seu aplicativo suporta Android 4.0 ou inferior, e incluem a Biblioteca de suporte vamos adicionar um elemento <meta-data>  dentro do <activity> . Em seguida, especifique a atividade pai como o valor de android.support.PARENT_ACTIVITY , combinando com o atributo android:parentActivityName.

Exemplo:

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

Agora vamos adicionar o botão de ação na ActionBar (com o comando abaixo vai ser adicionado a seta indicadora na barra)

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

A ação de clique deve ser tratada no método onOptionsItemSelected da seguinte forma:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Id correspondente ao botão Up/Home da actionbar
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Analisando esse método vemos a utilização do NavUtils, Quando você chamar o método navigateUpFromSameTask, a atividade termina e começa (ou recomeça) a atividade pai apropriado. Se a atividade pai de destino está na pilha de volta da tarefa, ele é levado para frente, conforme definido pela FLAG_ACTIVITY_CLEAR_TOP. Ou seja, sua atividade será reiniciada e colocada no topo da pilha.

No entanto, o navigateUpFromSameTask() é indicado apenas quando o seu aplicativo é o proprietário da tarefa atual (ou seja, o usuário começou esta tarefa a partir de seu aplicativo).

Se a sua atividade fornece quaisquer intent-filter que permitem que outros aplicativos  iniciem essa atividade, você deve implementar a ação de outra maneira. Chamado shouldUpRecreateTask() vamos verificar se a instância da atividade atual existe na tarefa de outro aplicativo. Se ele retornar true, em seguida devemos construir uma nova tarefa com TaskStackBuilder . Caso contrário, você pode usar o método navigateUpFromSameTask() como mostrado acima.

Por exemplo:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Id correspondente ao botão Up/Home da actionbar
    case android.R.id.home:
        Intent upIntent = NavUtils.getParentActivityIntent(this);
        if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
            //Se a atividade não faz parte do aplicativo, criamos uma nova tarefa
            // para navegação com a pilha de volta sintetizada.
            TaskStackBuilder.create(this)
                    // Adiciona todas atividades parentes na pilha de volta
                    .addNextIntentWithParentStack(upIntent)
                    .startActivities();
        } else {
            //Se essa atividade faz parte da tarefa do app
            //navegamos para seu parente logico.
            NavUtils.navigateUpTo(this, upIntent);
        }
        return true;
    }
    return super.onOptionsItemSelected(item);
}

Em alguns casos, precisamos manter nossa instancia e não recriar a atividade pai, não sei se a melhor maneira seja essa, mas foi a melhor que achei para tal solução. Basta não adicionar as tags de navegação em seu Manifest e ao tratar o onOptionItemSelected() podemos fazer da seguinte maneira:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    // Id correspondente ao botão Up/Home da actionbar
    case android.R.id.home:
       finish();
    }
    return super.onOptionsItemSelected(item);
}

Desta maneira retomamos a instancia anterior sem usar o FLAG_ACTIVITY_CLEAR_TOP.

Fontes:
– Providing Up Navigation – http://goo.gl/039YIK
– Navigation with Back and Up – http://goo.gl/MXc5vb

Help DEV – Analista desenvolvedor Java / Android

http://helpdev.com.br/zarelli

6 thoughts on “Android – Implementando corretamente o botão voltar na ActionBar (Providing Up Navigation)

  1. Pingback: Aplicando o padrão Home as Up na ActionBar do ANDROID | Elessandra Estevão

  2. O post me ajudou bastante, porém não estava dando certo, o o problema estava na forma que está adicionando o botão UP. Verificando o blog http://www.aprendaandroidgratis.com.br/2013/10/action-bar.html vi que a sua forma de ativar o botão UP estava diferente da deles
    //adicionando botão UP
    ActionBar actionbar = getSupportActionBar();
    actionbar.setDisplayHomeAsUpEnabled(true);

    porém o código para a ação do clique funcionou perfeitamente e complementou o que foi passado no outro blog. Muito obrigado

Deixe uma resposta

O seu endereço de email não será publicado Campos obrigatórios são marcados *

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>