Pergunta: Como se cria um retorno de chamada de um DialogFragment para outro Fragmento. No meu caso, a Atividade envolvida deve desconhecer completamente o DialogFragment.
Considere que eu tenho
public class MyFragment extends Fragment implements OnClickListener
Então, em algum momento eu poderia fazer
DialogFragment dialogFrag = MyDialogFragment.newInstance(this);
dialogFrag.show(getFragmentManager, null);
Onde se parece o MyDialogFragment
protected OnClickListener listener;
public static DialogFragment newInstance(OnClickListener listener) {
DialogFragment fragment = new DialogFragment();
fragment.listener = listener;
return fragment;
}
Mas não há garantia de que o ouvinte estará presente se o DialogFragment for pausado e retomado durante o seu ciclo de vida. As únicas garantias em um fragmento são aquelas transmitidas por meio de um pacote via setArguments e getArguments.
Existe uma maneira de referenciar a atividade se ela deve ser o ouvinte:
public Dialog onCreateDialog(Bundle bundle) {
OnClickListener listener = (OnClickListener) getActivity();
....
return new AlertDialog.Builder(getActivity())
........
.setAdapter(adapter, listener)
.create();
}
Mas não quero que a Atividade ouça eventos, preciso de um Fragmento. Realmente, poderia ser qualquer objeto Java que implemente o OnClickListener.
Considere o exemplo concreto de um fragmento que apresenta um AlertDialog via DialogFragment. Possui botões Sim / Não. Como posso enviar esses pressionamentos de botão de volta ao fragmento que o criou?
fonte
OnClickListener listener = (OnClickListener) getParentFragment();
no DialogFragment e seu Fragmento principal implementa a interface como você fez originalmente.Respostas:
A atividade envolvida desconhece completamente o DialogFragment.
Classe de fragmento:
Classe DialogFragment:
fonte
setTargetFragment
egetTargetFragment
. O uso deonActivityResult
é um pouco incerto. Provavelmente, seria melhor declarar seu próprio método específico no chamador do Fragment e usá-lo, em vez de redefinir o propósito em ActivityResult. Mas é tudo semântica nesse ponto.A solução TargetFragment não parece a melhor opção para fragmentos de diálogo, pois pode ser criada
IllegalStateException
após a destruição e a recriação do aplicativo. Nesse caso,FragmentManager
não foi possível encontrar o fragmento de destino e você receberá umaIllegalStateException
mensagem como esta:Parece que
Fragment#setTargetFragment()
não se destina à comunicação entre um fragmento filho e pai, mas para a comunicação entre fragmentos de irmãos.Portanto, uma maneira alternativa é criar fragmentos de diálogo como este usando o
ChildFragmentManager
fragmento pai, em vez de usar as atividadesFragmentManager
:E, usando uma Interface, no
onCreate
método da,DialogFragment
você pode obter o fragmento pai:Só resta chamar o método de retorno de chamada após essas etapas.
Para obter mais informações sobre o problema, acesse o link: https://code.google.com/p/android/issues/detail?id=54520
fonte
Eu segui estes passos simples para fazer essas coisas.
DialogFragmentCallbackInterface
com algum método comocallBackMethod(Object data)
. Qual você chamaria para passar dados.DialogFragmentCallbackInterface
interface em seu fragmento comoMyFragment implements DialogFragmentCallbackInterface
No momento da
DialogFragment
criação, defina seu fragmento de chamadaMyFragment
como fragmento de destino que criou,DialogFragment
usemyDialogFragment.setTargetFragment(this, 0)
check setTargetFragment (Fragmento de fragmento, int requestCode)Coloque seu objeto de fragmento de destino no seu
DialogFragment
chamandogetTargetFragment()
e faça aDialogFragmentCallbackInterface
conversão para .Agora você pode usar essa interface para enviar dados para o seu fragmento.É tudo feito! apenas verifique se você implementou essa interface no seu fragmento.
fonte
onActivityResult(request code, resultcode, intent)
para retornar o resultado ao fragmento1. Do fragmento1setTargetFragment()
e do fragmento2, usegetTargetFragment()
. Ao usar o fragmento pai / filho em um fragmento ou a atividade em um fragmento, você pode usar o ouvinte ou o retorno de chamada, pois não há perigo de vazar o pai no fragmento filho.Talvez um pouco tarde, mas possa ajudar outras pessoas com a mesma pergunta que eu.
Você pode usar
setTargetFragment
onDialog
antes de mostrar, e na caixa de diálogo que você pode chamargetTargetFragment
para obter a referência.fonte
O guia Comunicação com outros fragmentos diz que os fragmentos devem se comunicar por meio da atividade associada .
fonte
Você deve definir um
interface
em sua classe de fragmento e implementar essa interface em sua atividade pai. Os detalhes estão descritos aqui http://developer.android.com/guide/components/fragments.html#EventCallbacks . O código seria semelhante a:Fragmento:
Atividade:
fonte
FragmentA
e ele está assumindo que uma atividade é umOnArticleSelectedListener
, não o fragmento que o iniciou.MyFragment
você pode querer passar a usar um regularAlertDialog
A maneira correta de definir um ouvinte para um fragmento é definindo-o quando está anexado . O problema que tive foi que onAttachFragment () nunca foi chamado. Após alguma investigação, percebi que estava usando getFragmentManager em vez de getChildFragmentManager
Aqui está como eu faço isso:
Anexe-o no onAttachFragment:
fonte
De acordo com a documentação oficial:
Fragmento # setTargetFragment
Fragmento # getTargetFragment
Então você pode fazer isso:
fonte
Eu estava enfrentando um problema semelhante. A solução que eu descobri foi:
Declare uma interface no seu DialogFragment, como James McCracken explicou acima.
Implemente a interface em sua atividade (não fragmento! Essa não é uma boa prática).
No método de retorno de chamada em sua atividade, chame uma função pública necessária em seu fragmento, que executa o trabalho que você deseja executar.
Assim, torna-se um processo de duas etapas: DialogFragment -> Activity e depois Activity -> Fragment
fonte
Estou obtendo resultado para Fragment DashboardLiveWall (fragmento de chamada) do Fragment LiveWallFilterFragment (fragmento de recebimento) Assim ...
Onde
setResult de volta à chamada fragmento como
onActivityResult
fonte
Atualizada:
Eu criei uma biblioteca baseada no meu código de essência que gera as transmissões para você usando
@CallbackFragment
e@Callback
.https://github.com/zeroarst/callbackfragment .
E o exemplo fornece o exemplo que envia um retorno de chamada de um fragmento para outro fragmento.
Resposta antiga:
Eu fiz uma
BaseCallbackFragment
anotação@FragmentCallback
. AtualmenteFragment
, ele se estende , você pode alterá-lo paraDialogFragment
e irá funcionar. Ele verifica as implementações na seguinte ordem: getTargetFragment ()> getParentFragment ()> context (activity).Então você só precisa estendê-lo, declarar suas interfaces no seu fragmento e fornecer a anotação, e o fragmento base fará o resto. A anotação também possui um parâmetro
mandatory
para você determinar se deseja forçar o fragmento a implementar o retorno de chamada.https://gist.github.com/zeroarst/3b3f32092d58698a4568cdb0919c9a93
fonte
Pessoal Kotlin aqui vamos nós!
Portanto, o problema que temos é que criamos uma atividade,
MainActivity
nessa atividade criamos um fragmentoFragmentA
e agora queremos criar um fragmento de diálogo em cima deFragmentA
chamá-loFragmentB
. Como obtemos os resultados deFragmentB
voltaFragmentA
sem passarMainActivity
?Nota:
FragmentA
é um fragmento filho deMainActivity
. Para gerenciar fragmentos criadosFragmentA
, usaremos ochildFragmentManager
que faz isso!FragmentA
é um fragmento pai deFragmentB
, para acessarFragmentA
de dentroFragmentB
, usaremosparenFragment
.Dito isto, por dentro
FragmentA
,Aqui está o fragmento de diálogo
FragmentB
.Aqui está a interface que liga os dois.
É isso aí.
fonte
Eu resolvi isso de uma maneira elegante com o RxAndroid. Receba um observador no construtor do DialogFragment e assine o observable e empurre o valor quando o retorno de chamada estiver sendo chamado. Em seu Fragmento, crie uma classe interna do Observador, crie uma instância e passe-a no construtor do DialogFragment. Usei WeakReference no observador para evitar vazamentos de memória. Aqui está o código:
BaseDialogFragment.java
DatePickerFragment.java
MyFragment.java
Você pode ver o código fonte aqui: https://github.com/andresuarezz26/carpoolapp
fonte