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.
Design de caixas de diálogo
Para ver mais informações sobre como projetar caixas de diálogo, inclusive recomendações para o idioma, leia o guia de design 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
- Uma caixa de diálogo pode exibir um título, até três botões, uma lista de itens selecionáveis ou um layout personalizado.
DatePickerDialog
ouTimePickerDialog
- Uma caixa de diálogo com uma IU pré definida que permite ao usuário selecionar uma data ou hora.
Cuidado: o Android inclui outra classe de caixa de diálogo chamada
ProgressDialog
, que exibe uma caixa de diálogo com uma barra de progresso.
Esse widget está obsoleto porque impede que os usuários interajam com o
aplicativo enquanto o progresso está sendo exibido. Se for necessário indicar o carregamento ou
o progresso indeterminado, siga as diretrizes de design paraProgresso e atividade e use
umProgressBar
no seu layout, em vez de ProgressDialog
.
Essas classes definem o estilo e a estrutura da sua caixa de diálogo, mas você deve
usar um DialogFragment
como um contêiner para sua caixa de diálogo.
A classe DialogFragment
fornece todos os controles
necessários para criar sua 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 a IU da caixa de diálogo deve aparecer 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 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, é possível usar DialogFragment
e uma variedade de outras
APIs em dispositivos que executam o Android 1.6 ou versão mais recentes. Se a versão mínima compatível com seu aplicativo
for a API de nível 11 ou mais recentes, será possível usar a versão de framework de DialogFragment
, mas esteja ciente de que os links neste documento são para APIs
da biblioteca de suporte. Ao usar a biblioteca de suporte,
verifique se importou a classe android.support.v4.app.DialogFragment
e não a android.app.DialogFragment
.
Como criar um fragmento de caixa de diálogo
É possível criar vários designs de caixas de diálogo, inclusive
layouts personalizados e outros descritos no guia de design Caixas de diálogo (link em inglês),
estendendo
DialogFragment
e criando uma AlertDialog
no método de callback onCreateDialog()
.
Por exemplo, veja a seguir uma AlertDialog
básica gerenciada dentro de
um DialogFragment
:
Kotlin
class StartGameDialogFragment : DialogFragment() { override fun onCreateDialog(savedInstanceState: Bundle): Dialog { return activity?.let { // Use the Builder class for convenient dialog construction val builder = AlertDialog.Builder(it) builder.setMessage(R.string.dialog_start_game) .setPositiveButton(R.string.start, DialogInterface.OnClickListener { dialog, id -> // START THE GAME! }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> // User cancelled the dialog }) // Create the AlertDialog object and return it builder.create() } ?: throw IllegalStateException("Activity cannot be null") } }
Java
public class StartGameDialogFragment 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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // START THE GAME! } }) .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 callback 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 que você crie uma variedade de designs de caixas de diálogo, e
geralmente é a única classe necessária.
Como mostrado na figura 2, existem três regiões de uma caixa de diálogo de alerta:

Figura 2. Layout de uma caixa de diálogo.
- Título
É opcional e deve ser usado somente quando a área do conteúdo estiver ocupada por uma mensagem detalhada, uma lista ou um 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.
- Área de conteúdo
Pode exibir uma mensagem, uma lista ou outro layout personalizado.
- 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 um AlertDialog
com esses tipos de conteúdo, inclusive um layout personalizado.
Para criar um AlertDialog
:
Kotlin
// 1. Instantiate an <code><a href="/reference/android/app/AlertDialog.Builder.html">AlertDialog.Builder</a></code> with its constructor val builder: AlertDialog.Builder? = activity?.let { AlertDialog.Builder(it) } // 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 <code><a href="/reference/android/app/AlertDialog.html">AlertDialog</a></code> from <code><a href="/reference/android/app/AlertDialog.Builder.html#create()">create()</a></code> val dialog: AlertDialog? = builder?.create()
Java
// 1. Instantiate an <code><a href="/reference/android/app/AlertDialog.Builder.html">AlertDialog.Builder</a></code> 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 <code><a href="/reference/android/app/AlertDialog.html">AlertDialog</a></code> from <code><a href="/reference/android/app/AlertDialog.Builder.html#create()">create()</a></code> 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()
:
Kotlin
val alertDialog: AlertDialog? = activity?.let { val builder = AlertDialog.Builder(it) builder.apply { setPositiveButton(R.string.ok, DialogInterface.OnClickListener { dialog, id -> // User clicked OK button }) setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> // User cancelled the dialog }) } // Set other dialog properties ... // Create the AlertDialog builder.create() }
Java
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 ser realizada
quando o usuário pressionar o botão.
Há três botões de ação que podem ser adicionados:
- Positivo
- Você deve usar essa opção para aceitar e continuar a ação (a ação "OK").
- Negativo
- É o que se deve usar para cancelar a ação.
- Indiferente
- É o que se deve usar quando houver a opção do 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 "Lembrar 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()
:
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) builder.setTitle(R.string.pick_color) .setItems(R.array.colors_array, DialogInterface.OnClickListener { dialog, which -> // The 'which' argument contains the index position // of the selected item }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
@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 do conteúdo da caixa de diálogo,
a caixa não pode exibir uma mensagem e uma lista ao mesmo tempo, e será preciso definir um título para
ela 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 optar por retroceder a lista com um ListAdapter
,
use sempre um Loader
para que o conteúdo seja carregado
assincronamente. Veja mais detalhes sobre isso nos guias
Criação de layouts
com um adaptador e Carregadores.
Observação: por padrão, tocar em um item de lista dispensa a caixa de diálogo, a menos que você esteja usando uma das listas de opções persistentes a seguir.
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.

Figura 4. Lista de itens de múltipla escolha.
Por exemplo, veja como criar uma lista de múltipla escolha como a
ilustrada na figura 4, que salva os itens selecionados em um ArrayList
:
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val selectedItems = ArrayList<Int>() // Where we track the selected items val builder = AlertDialog.Builder(it) // 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, DialogInterface.OnMultiChoiceClickListener { dialog, which, isChecked -> if (isChecked) { // If the user checked the item, add it to the selected items selectedItems.add(which) } else if (selectedItems.contains(which)) { // Else, if the item is already in the array, remove it selectedItems.remove(which) } }) // Set the action buttons .setPositiveButton(R.string.ok, DialogInterface.OnClickListener { dialog, id -> // User clicked OK, so save the selectedItems results somewhere // or return them to the component that opened the dialog ... }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> ... }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { selectedItems = 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 selectedItems.add(which); } else if (selectedItems.contains(which)) { // Else, if the item is already in the array, remove it selectedItems.remove(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 selectedItems 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 uma lista tradicional e uma com botões de opção
forneçam uma ação de "escolha única", use setSingleChoiceItems()
se você quiser mantê-la.
Ou seja, se você quiser que a abertura da caixa de diálogo novamente mais tarde indique a opção atual do usuário,
crie uma lista com os botões de opção.
Criação de layout personalizado

Figura 5. Layout personalizado da caixa de diálogo.
Se você quiser um layout personalizado em uma caixa de diálogo, crie um layout e adicione-o a um
AlertDialog
chamando setView()
no seu 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, veja 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 fontes é definida como de fonte monoespaçada. Portanto,
você deve alterar sua família de fontes para "sans-serif"
, de modo que ambos os campos de texto usem
um estilo de fonte correspondente.
Para inflar o layout no DialogFragment
,
tenha um LayoutInflater
com
getLayoutInflater()
e chame
inflate()
, em que o primeiro parâmetro
é a identificação do recurso do layout e o segundo é uma exibição parental do layout.
Você pode chamar setView()
para colocar o layout na caixa de diálogo.
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { return activity?.let { val builder = AlertDialog.Builder(it) // Get the layout inflater val inflater = requireActivity().layoutInflater; // 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, DialogInterface.OnClickListener { dialog, id -> // sign in the user ... }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> getDialog().cancel() }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
@Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); // Get the layout inflater LayoutInflater inflater = requireActivity().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ê quiser uma caixa de diálogo personalizada,
poderá 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" >
É isso. 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 da lista,
o DialogFragment
pode realizar a ação
necessária por conta própria, mas normalmente será preciso fornecer o evento à atividade ou ao fragmento que
abriu a caixa de diálogo. Para fazer isso, defina uma interface com um método para cada tipo de evento de clique.
Em seguida, implemente essa interface no componente host que
receberá os eventos de ação do diálogo.
Por exemplo, veja um DialogFragment
que define uma
interface usada para a entrega de eventos de volta à atividade do host:
Kotlin
class NoticeDialogFragment : DialogFragment() { // Use this instance of the interface to deliver action events internal lateinit var listener: NoticeDialogListener /* 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. */ interface NoticeDialogListener { fun onDialogPositiveClick(dialog: DialogFragment) fun onDialogNegativeClick(dialog: DialogFragment) } // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener override fun onAttach(context: Context) { super.onAttach(context) // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host listener = context as NoticeDialogListener } catch (e: ClassCastException) { // The activity doesn't implement the interface, throw exception throw ClassCastException((context.toString() + " must implement NoticeDialogListener")) } } }
Java
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 listener; // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener @Override public void onAttach(Context context) { super.onAttach(context); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host listener = (NoticeDialogListener) context; } 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 um implementação da interface NoticeDialogListener
:
Kotlin
class MainActivity : FragmentActivity(), NoticeDialogFragment.NoticeDialogListener { fun showNoticeDialog() { // Create an instance of the dialog fragment and show it val dialog = NoticeDialogFragment() dialog.show(supportFragmentManager, "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 fun onDialogPositiveClick(dialog: DialogFragment) { // User touched the dialog's positive button } override fun onDialogNegativeClick(dialog: DialogFragment) { // User touched the dialog's negative button } }
Java
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 callback onAttach()
exibido acima, o fragmento da caixa de diálogo pode usar
os métodos de callback da interface para entregar eventos de clique à atividade:
Kotlin
override fun onCreateDialog(savedInstanceState: Bundle): Dialog { return activity?.let { // Build the dialog and set up the button click handlers val builder = AlertDialog.Builder(it) builder.setMessage(R.string.dialog_start_game) .setPositiveButton(R.string.start, DialogInterface.OnClickListener { dialog, id -> // Send the positive button event back to the host activity listener.onDialogPositiveClick(this) }) .setNegativeButton(R.string.cancel, DialogInterface.OnClickListener { dialog, id -> // Send the negative button event back to the host activity listener.onDialogNegativeClick(this) }) builder.create() } ?: throw IllegalStateException("Activity cannot be null") }
Java
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_start_game) .setPositiveButton(R.string.start, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the positive button event back to the host activity listener.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 listener.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 ter o FragmentManager
, chame
getSupportFragmentManager()
do
FragmentActivity
ou getFragmentManager()
de um Fragment
. Exemplo:
Kotlin
fun confirmStartGame() { val newFragment = StartGameDialogFragment() newFragment.show(supportFragmentManager, "game") }
Java
public void confirmStartGame() { DialogFragment newFragment = new StartGameDialogFragment(); newFragment.show(getSupportFragmentManager(), "game"); }
O segundo argumento, "game"
, é um nome de tag exclusivo que o sistema usa para salvar
e restaurar o estado do fragmento quando necessário. Para que a tag receba um identificador
do fragmento, chame findFragmentByTag()
.
Exibição de uma caixa de diálogo em tela cheia ou como um fragmento incorporado
Talvez você tenha um projeto de IU em que uma parte dela 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
quiser que o DialogFragment
seja
incorporável, defina a IU da caixa de diálogo em um layout e carregue o layout no
callback onCreateView()
.
Veja 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
):
Kotlin
class CustomDialogFragment : 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 fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { // 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 fun onCreateDialog(savedInstanceState: Bundle): Dialog { // 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. val dialog = super.onCreateDialog(savedInstanceState) dialog.requestWindowFeature(Window.FEATURE_NO_TITLE) return dialog } }
Java
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:
Kotlin
fun showDialog() { val fragmentManager = supportFragmentManager val newFragment = CustomDialogFragment() if (isLargeLayout) { // 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 val 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() } }
Java
public void showDialog() { FragmentManager fragmentManager = getSupportFragmentManager(); CustomDialogFragment newFragment = new CustomDialogFragment(); if (isLargeLayout) { // 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 ver 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 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, veja 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:
Kotlin
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) isLargeLayout = resources.getBoolean(R.bool.large_layout) }
Java
boolean isLargeLayout; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); isLargeLayout = 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
ter o mesmo resultado exibindo um 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 ver mais informações sobre como 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, será possível dispensá-la manualmente
chamando dismiss()
no DialogFragment
.
Caso seja necessário realizar determinadas
ações quando a caixa de diálogo é dispensada, será possível implementar o método onDismiss()
no DialogFragment
.
Também é possível cancelar uma caixa de diálogo. Esse é um evento especial que indica que o usuário
deixou explicitamente a 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
o onDismiss()
em cada evento que
invoca o callback onCancel()
. Entretanto,
se você chamar Dialog.dismiss()
ou DialogFragment.dismiss()
,
o sistema chamará onDismiss()
,
mas não onCancel()
. Portanto, em geral, é preciso
chamar dismiss()
quando o usuário pressiona o
botão positivo na caixa de diálogo para removê-la da exibição.