lightbulb_outline Help shape the future of the Google Play Console, Android Studio, and Firebase. Start survey

Caixas de diálogo

As caixas de diálogo são pequenas janelas que levam o usuário a tomar uma decisão ou inserir informações adicionais. Elas não ocupam toda a tela e são normalmente usadas para eventos modais que exijam que usuários realizem uma ação antes de continuar.

Projeto de caixas de diálogo

Para obter mais informações sobre como projetar caixas de diálogo, inclusive sobre recomendações de idioma, leia o guia de projeto de Caixas de diálogo.

A classe Dialog é a classe de base para caixas de diálogo, mas você deve evitar instanciar Dialog diretamente. Em vez disso, use uma das subclasses a seguir:

AlertDialog
Caixa de diálogo que pode exibir um título, até três botões, uma lista de itens selecionáveis ou um layout personalizado.
DatePickerDialog ou TimePickerDialog
Caixa de diálogo com uma IU predefinida que permite ao usuário selecionar uma data ou hora.

Essas classes definem o estilo e a estrutura da caixa de diálogo, mas deve-se usar um DialogFragment como um contêiner para a caixa de diálogo. A classe DialogFragment fornece todos os controles necessários para criar uma caixa de diálogo e gerenciar sua aparência em vez de chamar métodos no objeto Dialog.

O uso de DialogFragment para gerenciar a caixa de diálogo garante que ela processe corretamente os eventos de ciclos de vida, como quando o usuário pressiona o botão Voltar ou gira a tela. A classe DialogFragment também permite a reutilização da IU da caixa de diálogo como um componente incorporável em uma IU maior, assim como um Fragment tradicional (como nas vezes em que se deseja que a IU da caixa de diálogo apareça de modos diferentes em telas grandes e pequenas).

As seções a seguir neste guia descrevem como usar um DialogFragment combinado com um objeto AlertDialog. Se você quiser criar um seletor de data ou hora, leia o guia Seletores.

Observação: como a classe DialogFragment foi adicionada originalmente com o Android 3.0 (API de nível 11), este documento descreve como usar a classe DialogFragment fornecida com a Biblioteca de Suporte. Ao adicionar essa biblioteca ao aplicativo, pode-se usar DialogFragment e uma variedade de outras APIs em dispositivos que executam o Android 1.6 ou versão posterior. Se a versão mais antiga com a qual seu aplicativo é compatível for a API de nível 11 ou versão posterior, será possível usar a versão de DialogFragment da estrutura de trabalho, mas esteja ciente de que os links neste documento são para APIs da biblioteca de suporte. Ao usar a biblioteca de suporte, certifique-se de importar a classe android.support.v4.app.DialogFragment e não a android.app.DialogFragment.

Criação de um fragmento de caixa de diálogo

É possível realizar uma grande variedade de projetos de caixas de diálogo — inclusive layouts personalizados e outros descritos no guia de projeto Caixas de diálogo —, estendendo DialogFragment e criando uma AlertDialog no método de retorno de chamada onCreateDialog().

Por exemplo, a seguir há um AlertDialog básico gerenciado dentro de um DialogFragment:

public class FireMissilesDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // FIRE ZE MISSILES!
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();
    }
}

Figura 1. Caixa de diálogo com uma mensagem e dois botões de ação.

Agora, ao criar uma instância dessa classe e chamar show() nesse objeto, a caixa de diálogo será exibida como ilustrado na figura 1.

A próxima seção descreve em mais detalhes o uso das APIs AlertDialog.Builder para a criação de uma caixa de diálogo.

Conforme o nível de complexidade da caixa de diálogo, é possível implementar diversos outros métodos de retorno de chamada no DialogFragment, inclusive todos os métodos de ciclo de vida de fragmentos básicos.

Construção de uma caixa de diálogo de alerta

A classe AlertDialog permite a criação de diversos projetos de caixa de diálogo e normalmente é a única classe de caixa de diálogo necessária. Como ilustrado na figura 2, há três regiões de uma caixa de diálogo de alerta:

Figura 2. Layout de uma caixa de diálogo.

  1. Título

    É opcional e deve ser usado somente quando a área do conteúdo estiver ocupada por uma mensagem detalhada, uma lista ou layout personalizado. Se for necessário declarar uma mensagem ou pergunta simples (como a caixa de diálogo na figura 1), o título não é necessário.

  2. Área do conteúdo

    Pode exibir uma mensagem, uma lista ou outro layout personalizado.

  3. Botões de ação

    Não deve haver mais de três botões em uma caixa de diálogo.

A classe AlertDialog.Builder fornece APIs que permitem a criação de uma AlertDialog com esses tipos de conteúdo, inclusive um layout personalizado.

Para criar uma AlertDialog:

// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(R.string.dialog_message)
       .setTitle(R.string.dialog_title);

// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();

Os tópicos a seguir mostram como definir diversos atributos de caixas de diálogo com a classe AlertDialog.Builder.

Adição de botões

Para adicionar botões de ação como os da figura 2, chame os métodos setPositiveButton() e setNegativeButton():

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User clicked OK button
           }
       });
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User cancelled the dialog
           }
       });
// Set other dialog properties
...

// Create the AlertDialog
AlertDialog dialog = builder.create();

Os métodos set...Button() exigem um título para o botão (fornecido por um recurso de string) e um DialogInterface.OnClickListener que defina a ação a realizar quando o usuário pressionar o botão.

Há três botões de ação que podem ser adicionados:

Positivo
É o que se deve usar para aceitar e continuar a ação (a ação "OK").
Negativo
É o que se deve usar para cancelar a ação.
Neutro
É o que se deve usar quando houver a opção de o usuário não querer continuar a ação, mas não necessariamente cancelá-la. Ele aparece entre os botões positivo e negativo. Por exemplo, a ação pode ser "Notifique-me mais tarde".

Somente é possível adicionar um dos tipos de cada botão a um AlertDialog. ou seja, não é possível ter mais de um botão "positivo".

Figura 3. Caixa de diálogo com um título e uma lista.

Adição de listas

Há três tipos de listas disponíveis nas APIs AlertDialog:

  • Lista de escolha única tradicional
  • Lista de escolha única persistente (botões de opção)
  • Lista de escolhas múltiplas persistentes (caixas de seleção)

Para criar uma lista de escolha única como a da figura 3, use o método setItems():

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.pick_color)
           .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int which) {
               // The 'which' argument contains the index position
               // of the selected item
           }
    });
    return builder.create();
}

Como a lista aparece na área de conteúdo da caixa de diálogo, ela não pode exibir ao mesmo tempo uma mensagem e uma lista. Será necessário definir um título para a caixa de diálogo com setTitle(). Para especificar os itens da lista, chame setItems(), passando uma matriz. Como alternativa, é possível especificar uma lista usando setAdapter(). Isso permite retroceder a lista com dados dinâmicos (como os de um banco de dados) com um ListAdapter.

Se você optar por retroceder a lista com um ListAdapter, sempre use um Loader para que o conteúdo carregue assincronamente. Veja mais detalhes sobre isso nos guias Criação de layouts com um adaptador e Carregadores.

Observação: Por padrão, o toque em um item de lista dispensa a caixa de diálogo, a menos que você esteja usando uma das listas de escolha persistentes a seguir.

Figura 4. Lista de itens de múltipla escolha.

Adição de uma lista de escolha única ou de múltipla escolha persistente

Para adicionar uma lista de itens de múltipla escolha (caixas de seleção) ou itens de escolha única (botões de opção), use os métodos setMultiChoiceItems() ou setSingleChoiceItems(), respectivamente.

Por exemplo, eis como criar uma lista de múltipla escolha como a ilustrada na figura 4, que salva os itens selecionados em uma ArrayList:

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    mSelectedItems = new ArrayList();  // Where we track the selected items
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Set the dialog title
    builder.setTitle(R.string.pick_toppings)
    // Specify the list array, the items to be selected by default (null for none),
    // and the listener through which to receive callbacks when items are selected
           .setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checked the item, add it to the selected items
                       mSelectedItems.add(which);
                   } else if (mSelectedItems.contains(which)) {
                       // Else, if the item is already in the array, remove it
                       mSelectedItems.remove(Integer.valueOf(which));
                   }
               }
           })
    // Set the action buttons
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // User clicked OK, so save the mSelectedItems results somewhere
                   // or return them to the component that opened the dialog
                   ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   ...
               }
           });

    return builder.create();
}

Embora tanto a lista tradicional quanto a lista com botões de opção ofereçam uma ação de "escolha única", use setSingleChoiceItems() se quiser persistir a escolha do usuário. Ou seja, se a caixa de diálogo abrir novamente mais tarde e precisar indicar qual é a escolha atual do usuário, crie uma lista com botões de opção.

Criação de layout personalizado

Figura 5. Layout personalizado da caixa de diálogo.

Se você deseja um layout personalizado em uma caixa de diálogo, crie um layout e adicione-o a uma AlertDialog chamando setView() no objeto AlertDialog.Builder.

Por padrão, o layout personalizado preenche a janela da caixa de diálogo, mas ainda é possível usar métodos AlertDialog.Builder para adicionar botões e um título.

Por exemplo, eis o arquivo de layout para a caixa de diálogo na figura 5:

res/layout/dialog_signin.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:src="@drawable/header_logo"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:scaleType="center"
        android:background="#FFFFBB33"
        android:contentDescription="@string/app_name" />
    <EditText
        android:id="@+id/username"
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="4dp"
        android:hint="@string/username" />
    <EditText
        android:id="@+id/password"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:fontFamily="sans-serif"
        android:hint="@string/password"/>
</LinearLayout>

Dica: Por padrão, ao definir um elemento EditText para usar o tipo de entrada "textPassword", a família da fonte é definida como de espaçamento uniforme. Portanto, altere a família da fonte para "sans-serif" para que os campos de texto usem um estilo de fonte compatível.

Para inflar o layout no DialogFragment, obtenha um LayoutInflater com getLayoutInflater() e chame inflate(), em que o primeiro parâmetro é o ID de recurso do layout e o segundo é uma exibição pai do layout. Em seguida, pode-se chamar setView() para posicionar o layout na caixa de diálogo.

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Get the layout inflater
    LayoutInflater inflater = getActivity().getLayoutInflater();

    // Inflate and set the layout for the dialog
    // Pass null as the parent view because its going in the dialog layout
    builder.setView(inflater.inflate(R.layout.dialog_signin, null))
    // Add action buttons
           .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // sign in the user ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   LoginDialogFragment.this.getDialog().cancel();
               }
           });
    return builder.create();
}

Dica: Se você deseja uma caixa de diálogo personalizada, pode exibir uma Activity como uma caixa de diálogo em vez de usar as APIs Dialog. Basta criar uma atividade e definir o tema como Theme.Holo.Dialog no elemento <activity> do manifesto:

<activity android:theme="@android:style/Theme.Holo.Dialog" >

Pronto. Agora a atividade é exibida em uma janela da caixa de diálogo em vez de tela cheia.

Direcionamento de eventos de volta ao host da caixa de diálogo

Quando o usuário toca em um dos botões de ação da caixa de diálogo ou seleciona um item de sua lista, o DialogFragment pode realizar a ação necessária sozinho, mas normalmente será necessário fornecer o evento à atividade ou ao fragmento que abriu a caixa de diálogo. Para isso, defina uma interface com um método para cada tipo de evento de clique. Em seguida, implemente essa interface no componente do host que receberá os eventos de ação da caixa de diálogo.

Por exemplo, eis um DialogFragment que define uma interface por meio da qual entrega os eventos de volta à atividade do host:

public class NoticeDialogFragment extends DialogFragment {

    /* The activity that creates an instance of this dialog fragment must
     * implement this interface in order to receive event callbacks.
     * Each method passes the DialogFragment in case the host needs to query it. */
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    // Use this instance of the interface to deliver action events
    NoticeDialogListener mListener;

    // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Verify that the host activity implements the callback interface
        try {
            // Instantiate the NoticeDialogListener so we can send events to the host
            mListener = (NoticeDialogListener) activity;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface, throw exception
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

A atividade que hospeda a caixa de diálogo cria uma instância da caixa com o construtor do fragmento da caixa de diálogo e recebe os eventos dela por meio de uma implementação da interface NoticeDialogListener:

public class MainActivity extends FragmentActivity
                          implements NoticeDialogFragment.NoticeDialogListener{
    ...

    public void showNoticeDialog() {
        // Create an instance of the dialog fragment and show it
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following methods
    // defined by the NoticeDialogFragment.NoticeDialogListener interface
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // User touched the dialog's positive button
        ...
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // User touched the dialog's negative button
        ...
    }
}

Como a atividade do host implementa o NoticeDialogListener — que é aplicado pelo método de retorno de chamada onAttach() exibido acima —, o fragmento da caixa de diálogo pode usar os métodos de retorno de chamada da interface para entregar eventos de clique à atividade:

public class NoticeDialogFragment extends DialogFragment {
    ...

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Build the dialog and set up the button click handlers
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the positive button event back to the host activity
                       mListener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the negative button event back to the host activity
                       mListener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
}

Exibição de uma caixa de diálogo

Para exibir a caixa de diálogo, crie uma instância do DialogFragment e chame show(), passando o FragmentManager e um nome de tag para o fragmento da caixa de diálogo.

Para obter o FragmentManager, chame getSupportFragmentManager() da FragmentActivity ou getFragmentManager() de um Fragment. Por exemplo:

public void confirmFireMissiles() {
    DialogFragment newFragment = new FireMissilesDialogFragment();
    newFragment.show(getSupportFragmentManager(), "missiles");
}

O segundo argumento, "missiles", é um nome de tag exclusivo que o sistema usa para salvar e restaurar o estado do fragmento quando necessário. Para que a tag obtenha um identificador do fragmento, chame findFragmentByTag().

Exibição de uma caixa de diálogo em tela cheia ou como um fragmento incorporado

Pode-se ter um projeto de IU em que uma parte da IU apareça como uma caixa de diálogo em determinadas situações, mas como tela cheia ou fragmento incorporado em outras (dependendo do tamanho da tela do dispositivo). A classe DialogFragment oferece essa flexibilidade porque ainda pode se comportar como um Fragment incorporável.

Contudo, não é possível usar AlertDialog.Builder nem outros objetos Dialog para criar a caixa de diálogo nesse caso. Se você deseja que DialogFragment seja incorporável, defina a IU da caixa de diálogo em um layout e carregue o layout no retorno de chamada onCreateView().

Eis um exemplo de DialogFragment que pode aparecer tanto como caixa de diálogo quanto como fragmento incorporável (usando um layout chamado purchase_items.xml):

public class CustomDialogFragment extends DialogFragment {
    /** The system calls this to get the DialogFragment's layout, regardless
        of whether it's being displayed as a dialog or an embedded fragment. */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout to use as dialog or embedded fragment
        return inflater.inflate(R.layout.purchase_items, container, false);
    }

    /** The system calls this only when creating the layout in a dialog. */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using onCreateView() is
        // to modify any dialog characteristics. For example, the dialog includes a
        // title by default, but your custom layout might not need it. So here you can
        // remove the dialog title, but you must call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

A seguir, veja alguns códigos que decidem por exibir o fragmento como uma caixa de diálogo ou como uma IU de tela cheia com base no tamanho da tela:

public void showDialog() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    CustomDialogFragment newFragment = new CustomDialogFragment();

    if (mIsLargeLayout) {
        // The device is using a large layout, so show the fragment as a dialog
        newFragment.show(fragmentManager, "dialog");
    } else {
        // The device is smaller, so show the fragment fullscreen
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // For a little polish, specify a transition animation
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity
        transaction.add(android.R.id.content, newFragment)
                   .addToBackStack(null).commit();
    }
}

Para obter mais informações sobre a realização de transações de fragmentos, consulte o guia Fragmentos.

Nesse exemplo, o booleano mIsLargeLayout especifica se o dispositivo atual deve usar o projeto de layout grande do aplicativo (e, portanto, exibir esse fragmento como uma caixa de diálogo em vez de tela cheia). O melhor modo de definir esse tipo de booleano é declarar um valor de recurso bool com um valor de recurso alternativo para diferentes tamanhos de tela. Por exemplo, eis duas versões de recurso bool para diferentes tamanhos de tela:

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

Assim, é possível inicializar o valor mIsLargeLayout durante o método onCreate() da atividade:

boolean mIsLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

Exibição de uma atividade como uma caixa de diálogo em telas grandes

Em vez de exibir uma caixa de diálogo como uma IU de tela cheia em telas pequenas, é possível obter o mesmo resultado exibindo uma Activity como uma caixa de diálogo em telas grandes. A abordagem escolhida depende do projeto do aplicativo, mas a exibição de uma atividade como caixa de diálogo normalmente é útil quando o aplicativo já está projetado para telas pequenas e é preciso melhorar a experiência em tablets exibindo uma atividade de vida curta como uma caixa de diálogo.

Para exibir uma atividade como uma caixa de diálogo somente em telas grandes, aplique o tema Theme.Holo.DialogWhenLarge no elemento <activity> do manifesto:

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >

Para obter mais informações sobre estilizar as atividades com temas, consulte o guia Estilos e temas.

Dispensa de uma caixa de diálogo

Quando o usuário toca em qualquer botão de ação criado com um AlertDialog.Builder, o sistema dispensa a caixa de diálogo.

O sistema também dispensa a caixa de diálogo quando o usuário toca em um item em uma lista da caixa de diálogo, exceto quando a lista usa botões de opção ou caixas de seleção. Caso contrário, é possível dispensá-la manualmente chamando dismiss() no DialogFragment.

Caso seja necessário realizar determinadas ações quando a caixa de diálogo é dispensada, é possível implementar o método onDismiss() no DialogFragment.

Também é possível cancelar uma caixa de diálogo. Trata-se de um evento especial que indica que o usuário se retirou explicitamente da caixa de diálogo sem concluir a tarefa. Isso ocorre se o usuário pressionar o botão Voltar, tocar na tela fora da área da caixa de diálogo ou se você chamar cancel() explicitamente no Dialog (como em resposta a um botão “Cancelar” na caixa de diálogo).

Como mostrado no exemplo acima, é possível responder ao evento de cancelamento implementando onCancel() na classe DialogFragment.

Observação: O sistema chama onDismiss() para cada evento que chama o retorno de chamada onCancel(). Entretanto, se você chamar Dialog.dismiss() ou DialogFragment.dismiss(), o sistema chamará onDismiss(), mas não onCancel(). Portanto, geralmente, deve-se chamar dismiss() quando o usuário pressiona o botão positivo na caixa de diálogo para removê-la da exibição.