Estou tentando evitar que os diálogos criados com o construtor Alert sejam descartados quando a atividade for reiniciada.
Se eu sobrecarregar o método onConfigurationChanged, posso fazer isso com êxito e redefinir o layout para a orientação correta, mas perco o recurso de texto fixo do edittext. Portanto, para resolver o problema do diálogo, criei este problema de edição de texto.
Se eu salvar as strings do texto de edição e reatribuí-las na alteração onCofiguration, elas ainda parecem ter como padrão o valor inicial, diferente do que foi inserido antes da rotação. Mesmo se eu forçar uma invalidação parece atualizá-los.
Eu realmente preciso resolver o problema de diálogo ou o problema de edição de texto.
Obrigado pela ajuda.
Respostas:
A melhor maneira de evitar esse problema hoje em dia é usando a
DialogFragment
.Crie uma nova classe que estenda
DialogFragment
. SubstituaonCreateDialog
e devolva seu antigoDialog
ou umAlertDialog
.Então você pode mostrar com
DialogFragment.show(fragmentManager, tag)
.Aqui está um exemplo com
Listener
:E na Activity você chama:
Essa resposta ajuda a explicar essas outras três perguntas (e suas respostas):
fonte
onAttach
está obsoleto agora. O que deve ser feito em vez disso?onAttach(Context context)
eandroid.support.v4.app.DialogFragment
. OonAttach
método usa emcontext
vez deactivity
um parâmetro agora.YesNoListener
. Veja esta resposta .fonte
Context
dentro dos botões de diálogoOnClickListener
.Se você estiver mudando o layout na mudança de orientação, eu não colocaria
android:configChanges="orientation"
em seu manifesto porque você está recriando as visualizações de qualquer maneira.Salve o estado atual de sua atividade (como texto inserido, caixa de diálogo exibida, dados exibidos etc.) usando estes métodos:
Dessa forma, a atividade passa por onCreate novamente e depois chama o método onRestoreInstanceState, onde você pode definir seu valor EditText novamente.
Se você deseja armazenar objetos mais complexos, você pode usar
Aqui você pode armazenar qualquer objeto e no onCreate basta chamar
getLastNonConfigurationInstance();
para pegar o objeto.fonte
OnRetainNonConfigurationInstance()
agora está obsoleto como o Doc diz: developer.android.com/reference/android/app/…setRetainInstance(boolean retain)
deve ser usado em seu lugar: developer.android.com/reference/android/app/…setRetainInstance
é completamente diferente: é para Fragments e não garante que a instância será retida.Basta adicionar android: configChanges = "idance "com seu elemento de atividade em AndroidManifest.xml
Exemplo:
fonte
Uma abordagem muito fácil é criar os diálogos a partir do método
onCreateDialog()
(veja a nota abaixo). Você mostra a elesshowDialog()
. Desta forma, o Android lida com a rotação para você e você não tem que chamardismiss()
emonPause()
para evitar uma WindowLeak e então você não tem que restaurar o diálogo. Dos documentos:Consulte a documentação do Android showDialog () para obter mais informações. Espero que ajude alguém!
Nota: Se estiver usando AlertDialog.Builder, não chame
show()
deonCreateDialog()
, chame emcreate()
vez disso. Se estiver usando ProgressDialog, basta criar o objeto, definir os parâmetros necessários e retorná-lo. Concluindo,show()
dentroonCreateDialog()
causa problemas, basta criar a instância Dialog e retorná-la. Isso deve funcionar! (Tive problemas ao usar showDialog () de onCreate () - na verdade não mostrando a caixa de diálogo -, mas se você usá-lo em onResume () ou em um retorno de chamada do ouvinte, ele funciona bem).fonte
AlertDialog.Builder
. Se você usar dentroonCreateDialog()
, em vez de usar,show()
retorne o resultado decreate()
.show()
Caso contrário , chame e armazene o AlertDialog retornado em um atributo da Activity eonPause()
dismiss()
nele se estiver mostrando para evitar um WindowLeak. Espero que ajude!Esta pergunta foi respondida há muito tempo.
No entanto, esta é uma solução simples e não hacky que eu uso para mim.
Fiz esta classe auxiliar para mim mesmo, então você também pode usá-la em seu aplicativo.
O uso é:
Ou
fonte
Você pode combinar os métodos onSave / onRestore do Dialog com os métodos onSave / onRestore da Activity para manter o estado do Dialog.
Nota: Este método funciona para aqueles Diálogos "simples", como a exibição de uma mensagem de alerta. Ele não reproduz o conteúdo de um WebView embutido em um Diálogo. Se você realmente deseja evitar que um diálogo complexo seja descartado durante a rotação, tente o método de Chung IW.
fonte
Definitivamente, a melhor abordagem é usar DialogFragment.
Aqui está minha solução de classe wrapper que ajuda a evitar que diferentes diálogos sejam descartados dentro de um Fragment (ou Activity com pequena refatoração). Além disso, ajuda a evitar a refatoração massiva de código se, por alguns motivos, houver muitos dados
AlertDialogs
espalhados no código, com pequenas diferenças entre eles em termos de ações, aparência ou outra coisa.Quando se trata de Activity, você pode invocar
getContext()
dentroonCreateDialog()
, lançar para aDialogProvider
interface e solicitar um diálogo específico pormDialogId
. Toda lógica para lidar com um fragmento de destino deve ser excluída.Uso do fragmento:
Você pode ler o artigo completo no meu blog. Como evitar que o Dialog seja descartado? e brincar com o código-fonte .
fonte
Parece que isso ainda é um problema, mesmo quando "está fazendo tudo certo" e usando
DialogFragment
etc.Há uma discussão no Google Issue Tracker que afirma que isso se deve a uma antiga mensagem de dispensa deixada na fila de mensagens. A solução alternativa fornecida é bastante simples:
Incrível que isso ainda seja necessário 7 anos depois que o problema foi relatado pela primeira vez.
fonte
Eu tive um problema semelhante: quando a orientação da tela mudou, o
onDismiss
ouvinte da caixa de diálogo foi chamado, embora o usuário não tenha dispensado a caixa de diálogo. Consegui contornar isso usando oonCancel
ouvinte, que disparou quando o usuário pressionou o botão Voltar e quando o usuário tocou fora da caixa de diálogo.fonte
Apenas use
e o aplicativo saberá como lidar com a rotação e o tamanho da tela.
fonte