this is how I call my DialogFragment
IncomeAdd dfIncomeAdd = IncomeAdd.newInstance(currentYear,currentMonth);
dfIncomeAdd.setTargetFragment(this, Activity.RESULT_OK);
dfIncomeAdd.show(getActivity().getSupportFragmentManager(),"fragmentDialog");
and I need the DialogFragment to return it's result to my calling fragment, so I use onActivityResult but it seems onActivityResult isn't being triggered. I read somewhere that I need to start the DialogFragment activity by calling it with StartActivityForResult. But how do I call StartActivityForResult when using newInstance?
Why do you need to call onActivityResult.
You can just create a method in your Activity class, say:
dialogListener(String... args) //data to be sent from dialog will go in as arguments, that's a var-arg syntax
{
//write code which you intented to write in onActivityResult
}
call this method while you dismiss the dialog.
You can use following pattern. First create dialog listener:
public class IncomeAdd extends DialogFragment {
public interface OnSomethingChanged {
public void onChange(int value);
}
OnSomethingChanged mListener;
public void setListener(OnSomethingChanged l) {
mListener = l;
}
}
Now you should call mListener.onChange(dialogValue) when OK button is clicked:
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if(mListener != null) {
mListener.onDateChange(dialogValue);
}
}
});
Showing dialog:
IncomeAdd dfIncomeAdd = IncomeAdd.newInstance(currentYear,currentMonth);
dfIncomeAdd.setListener(new OnSomethingChanged() {
public void onChange(int value) {
// do with value what you want
}
});
dfIncomeAdd.show(getActivity(),"fragmentDialog");
Related
I am launching a DialogFragment from my Fragment and listening to an event in MainActivity when the button is pressed in Dialog Fragment.
This is the listener interface defined in DialogFragment :
public interface NewDialogListener {
public void onDialogPositiveClick(String data);
}
Instantiating the listener in DialogFragment:
#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 = (NewDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString()
+ " must implement NoticeDialogListener");
}
}
#Override
public AlertDialog onCreateDialog(Bundle savedInstanceState) {
currentActivity = getActivity();
newDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(positiveButtonViewOnClickListener);
...
return newDialog;
}
Firing the listener when positive button in DialogFragmentis clicked:
private DialogInterface.OnClickListener positiveButtonOnClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mListener.onDialogPositiveClick("positive");
}
};
And then I capture the listener in MainActivity :
#Override
public void onDialogPositiveClick(String status) {
Fragment fragment = getVisibleFragment();
if (fragment instanceof NewListFragment) {
((NewListFragment)fragment).updateView();
}
}
This works if I haven't changes the rotation of the device. But If I changes the rotation of the device and do the same thing again, the control never reaches onDialogPositiveClick.
What is that changes when device is rotated that could cause this?
Since the listener is the activity itself, you can just use it directly in the onClick via a call to getActivity(). You can put a try catch on the call to be safe. No need to set it to a variable.
Hi I am very new for android and I have created one Utils class and there I have created one Alert Dialogue box.
When I click "Ok" and "Cancel" buttons I want to handle that click Actions in my MainActivity using interface methods.
But using my below code I am getting exceptions like:
java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.venkat.implementinterfacemethods.CommonUtilities$BackGroundDialogeCall.doDialogueExecute(java.lang.String)' on a null object reference
CommonUtilities:-
public class CommonUtilities {
BackGroundDialogeCall backGroundDialogeCall;
public interface BackGroundDialogeCall {
void doDialogueExecute(String result);
}
//Adding Dialoge box:-
public void displaySignOutAlertDialog(Context activity) {
new AlertDialog.Builder(activity)
.setTitle("Alert")
.setMessage("Are you sure want to reserve?")
.setPositiveButton(android.R.string.yes,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
backGroundDialogeCall.doDialogueExecute("yes");
}
})
.setNegativeButton(android.R.string.no,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
backGroundDialogeCall.doDialogueExecute("no");
}
}).show();
}
}
MainActivity:-
public class MainActivity extends AppCompatActivity implements CommonUtilities.BackGroundDialogeCall {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CommonUtilities commonUtilities = new CommonUtilities();
commonUtilities.displaySignOutAlertDialog(MainActivity.this);
}
#Override
public void doDialogueExecute(String result) {
if(result.equals("yes")){
Log.d("=======>","if block");
}else{
Log.d("=======>","else block");
}
}
}
You have not initialized backGroundDialogeCall in CommonUtilities class that's why the null pointer exception.
You can initialize it inside your displaySignOutAlertDialog method like this:
backGroundDialogeCall = (BackGroundDialogeCall) activity;
For communicating between fragments and activities, check this out http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface
Note: The interface is initialized in onAttach method when using Fragments which are attached to an Activity.
For implementing interfaces other than activities; like adapters, you need a "Context" to initialize the interface.
Like this => backGroundDialogeCall = (BackGroundDialogeCall) activity;
Here, activity is the 'context'.
I have created ErrorDialogFragment which contains OnDialogClickListener parameter.
Every other Fragment or Activity that needs to show ErrorDialogFragment sets OnDialogClickListener via public method in ErrorDialogFragment. In the same time, all those activities and fragments implements OnDialogClickListener .
Problem occurs if user exits from application when ErrorDialogFragment is showed, and returns after a while (app is removed from memory). If user clicks on fragment options it will force close, because OnDialogClickListener is not set.
Am i wrong with with activity-listener-fragment pattern, and how do i solve this (application is in beta already.. big pattern change is not acceptable.
Eg:
Interface:
public interface OnDialogClickListener {
public void OnPositiveClick(int key, Object... args);
public void OnNegativeClick(int key, Object... args);
}
Activity:
public class Home extends FragmentActivity implements TabListener, ServiceConnection, OnDialogClickListener {
.
.
.
#Override
public void OnPositiveClick(int key, Object... args) {
//some actions
}
#Override
public void OnNegativeClick(int key, Object... args) {
//some actions
}
Fragment:
public class ErrorDialogFragment extends DialogFragment implements OnClickListener {
OnDialogClickListener OnDialogClickListener = null;
.
.
.
public void setDialogListener(OnDialogClickListener listener)
{
OnDialogClickListener = listener;
}
#Override
public void onClick(DialogInterface dialog, int which) {
if(OnDialogClickListener != null){
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
this.dismiss();
OnDialogClickListener.OnPositiveClick(KEY, args);
break;
default:
this.dismiss();
OnDialogClickListener.OnNegativeClick(KEY, args);
break;
}
}
else
this.dismiss();
}
You're way off better setting it in DialogFragment#onAttach(Activity) callback like this:
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mOnDialogClickListener = (OnDialogClickListener) activity;
} catch(ClassCastException e) {
throw new ClassCastException(activity.toString() + "must implement" + OnDialogClickListener.class.getSimpleName());
}
}
#Override
public void onDetach() {
super.onDetach()
mOnDialogClickListener = null;
}
And finally, obviously, make your Activity implements OnDialogClickListener
Just write this.dismiss() after OnDialogClickListener() callback.
#Override
public void onClick(DialogInterface dialog, int which) {
if(OnDialogClickListener != null){
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
OnDialogClickListener.OnPositiveClick(KEY, args);
this.dismiss();
break;
default:
OnDialogClickListener.OnNegativeClick(KEY, args);
this.dismiss();
break;
}
}
else
this.dismiss();
}
In all your onResume() methods of your Activities and Fragments, that implement OnDialogClickListener, you have to to make sure to get a hold of your DialogFragment instance and reset the listener of it.
You can get the reference from the FragmentManager.findFragmentByXyz() or by FragmentManager.getFragments()
Note, that on Compatibility Package V13 there is no FragmentManager.getFragments() (yet?! who knows...).
I am using a DialogFragment, which I am showing like this from an Activity:
DialogFragmentImage dialog = DialogFragmentImage.newInstance(createBitmap());
dialog.onDismiss(dialog);.onDismiss(this);
dialog.show(getFragmentManager(), "DialogFragmentImage");
I would like to check when the DialogFragment was dismissed (for example when the back button was pressed), but in my Activity. How can I do that? How can I "tell" my activity that the DialogFragment has been dismissed?
Make your Activity implement OnDismissListener
public final class YourActivity extends Activity implements DialogInterface.OnDismissListener {
#Override
public void onDismiss(final DialogInterface dialog) {
//Fragment dialog had been dismissed
}
}
DialogFragment already implements OnDismissListener, just override the method and call the Activity.
public final class DialogFragmentImage extends DialogFragment {
///blah blah
#Override
public void onDismiss(final DialogInterface dialog) {
super.onDismiss(dialog);
final Activity activity = getActivity();
if (activity instanceof DialogInterface.OnDismissListener) {
((DialogInterface.OnDismissListener) activity).onDismiss(dialog);
}
}
}
If you're starting the dialog from a fragment using the childFragment manager (API>=17), you can use getParentFragment to talk to the onDismissListener on the parent fragment.:
public final class DialogFragmentImage extends DialogFragment {
///blah blah
#Override
public void onDismiss(final DialogInterface dialog) {
super.onDismiss(dialog);
Fragment parentFragment = getParentFragment();
if (parentFragment instanceof DialogInterface.OnDismissListener) {
((DialogInterface.OnDismissListener) parentFragment).onDismiss(dialog);
}
}
}
Here is my answer. It's a bit late but it's maybe benefit someone passing by.
FragmentManager fm = getFragmentManager();
YourDialogFragment dialog = new YourDialogFragment();
dialog.show(fm,"MyDialog");
fm.executePendingTransactions();
dialog.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
//do whatever you want when dialog is dismissed
}
});
We need to call
fm.executePendingTransactions();
To make sure that FragmentTransaction work has been performed. Otherwise NullPointerException can occur when calling setOnDismissListener().
Sorry if there is any mistake. Hope this help.
This is an old issue but I found no solution I am happy with. I don't like passing any Listeners to my DialogFragment or set a TargetFragment, because that may break on orientation change. What do you think about this?
MyDialog d = new MyDialog();
d.show(fragmentManager, "tag");
fragmentManager.registerFragmentLifecycleCallbacks(new FragmentManager.FragmentLifecycleCallbacks() {
#Override
public void onFragmentViewDestroyed(FragmentManager fm, Fragment f) {
super.onFragmentViewDestroyed(fm, f);
//do sth
fragmentManager.unregisterFragmentLifecycleCallbacks(this);
}
}, false);
Alternative answer, if you don't have access to the methode onDismiss of activity.
//DIALOGFRAGMENT
//Create interface in your DialogFragment (or a new file)
public interface OnDismissListener {
void onDismiss(MyDialogFragment myDialogFragment);
}
//create Pointer and setter to it
private OnDismissListener onDismissListener;
public void setDissmissListener(DissmissListener dissmissListener) {
this.dissmissListener = dissmissListener;
}
//Call it on the dialogFragment onDissmiss
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if (onDismissListener != null) {
onDismissListener.onDismiss(this);
}
}
//OTHER CLASS, start fragment where you want
MyDialogFragment df = new MyDialogFragment();
df.setOnDismissListener(new MyDialogFragment.OnDismissListener() {
#Override
public void onDismiss(MyDialogFragment myDialogFragment) {
//Call when MyDialogFragment close
}
});
df.show(activity.getFragmentManager(), "myDialogFragment");
edit : if system need to recreate DialogFragment:
you can find it with
MyDialogFragment myDialogFragment = getFragmentManager().findFragmentByTag("MyDialogFragment");
if(myDialogFragment != null) {
myDialogFragment.setOnDismissListener(...);
}
public class OpcoesProdutoDialogo extends DialogFragment{
private DialogInterface.OnDismissListener onDismissOuvinte;
.
.
.
#Override
public void onDismiss(DialogInterface dialog) {
super.onDismiss(dialog);
if(onDismissOuvinte!=null)
onDismissOuvinte.onDismiss(dialog);
}
public void setOnDismissListener(#Nullable DialogInterface.OnDismissListener listener) {
this.onDismissOuvinte = listener;
}
}
and in call
OpcoesProdutoDialogo opcProduto = OpcoesProdutoDialogo.criar(itemPedido);
opcProduto.show(getFragmentManager(), "opc_produto_editar");
opcProduto.setOnDismissListener(d->{
adapterItens.notifyItemChanged(posicao);
});
You can subclass DialogFragment and provide your own listener that is going to be called and in onCancel.
var onDismissListener: (() -> Unit)? = null
For the ones not familiar with Kotlin this is just an anonymous interface that saves boilerplate iterface in Java. Use a field and a setter in Java.
And then in onCancel
override fun onCancel(dialog: DialogInterface?) {
super.onCancel(dialog)
onDismissListener?.invoke()
}
Have fun!
If you don't like the solution of #yaroslav-mytkalyk, in which the fragment needs to cast the activity / parent fragment, here's another one:
Here's the idea:
Expose a listener in your fragment, DialogFragmentImage.
Implement the listener in your activity and pass it to the fragment when creating it. Make sure to use a tag as well in order to be able to find the fragment later (read below).
In onStop(), remove the listener in order not to leak the activity if it's destroyed. This will happen when the screen is rotated, as the activity will be re-created.
In onResume(), check if the fragment exists and if yes, re-add the listener.
Expose a listener from your fragment:
class MyFragment extends DialogFragment {
public interface OnDismissListener {
void dismissed();
}
#Nullable
private OnDismissListener onDismissListener;
public void setOnDismissListener(#Nullable OnDismissListener onDismissListener) {
this.onDismissListener = onDismissListener;
}
/*
If you are calling dismiss() or dismissAllowingStateLoss() manually,
don't forget to call:
if (onDismissListener != null) {
onDismissListener.dismissed();
}
Otherwise, override them and call it there.
*/
}
And this is how your activity should look like:
class MyActivity extends AppCompatActivity {
private static final String MY_FRAGMENT_TAG = "my_fragment";
private MyFragment.OnDismissListener myFragmentListener = () -> {
// ...
};
/**
* Shows the fragment. Note that:
* 1. We pass a tag to `show()`.
* 2. We set the listener on the fragment.
*/
private void showFragment() {
MyFragment fragment = new MyFragment();
fragment.show(getSupportFragmentManager(), MY_FRAGMENT_TAG);
fragment.setOnDismissListener(myFragmentListener);
}
#Override
protected void onStart() {
super.onStart();
// Restore the listener that we may have removed in `onStop()`.
#Nullable MyFragment myFragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
if (myFragment != null) {
myFragment.setOnDismissListener(myFragmentListener);
}
}
#Override
protected void onStop() {
// If the fragment is currently shown, remove the listener so that the activity is not leaked when e.g. the screen is rotated and it's re-created.
#Nullable MyFragment myFragment = (MyFragment) getSupportFragmentManager().findFragmentByTag(MY_FRAGMENT_TAG);
if (myFragment != null) {
myFragment.setOnDismissListener(null);
}
super.onStop();
}
}
Care : all example aren't correct because your fragment should have a no-arg constructor !
Working code with back gesture and close button in the fragment itself. I removed useless code stuff like getting arg in onCreate etc.
Important : onDismiss is also call when orientation change so as a result you should check if the context is not null in your callback (or using other stuff).
public class MyDialogFragment extends DialogFragment {
public static String TAG = "MyFragment";
public interface ConfirmDialogCompliant {
void doOkConfirmClick();
}
public MyFragment(){
super();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
((ImageButton) rootView.findViewById(R.id.btn_close)).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// close fragment
dismiss();
}
});
return rootView;
}
#Override
public void onDismiss(#NonNull DialogInterface dialog) {
super.onDismiss(dialog);
// notify
if(caller != null)
caller.doOkConfirmClick();
}
}
public void setCallback(ConfirmDialogCompliant caller) {
this.caller = caller;
}
public static MyDialogFragment newInstance(String id) {
MyDialogFragment f = new MyDialogFragment();
// Supply num input as an argument.
Bundle args = new Bundle();
args.putString("YOU_KEY", id);
f.setArguments(args);
return f;
}
}
And now how to call it from parent.
MyDialogFragment.ConfirmDialogCompliant callback = new MyDialogFragment.ConfirmDialogCompliant() {
#Override
public void doOkConfirmClick() {
// context can be null, avoid NPE
if(getContext() != null){
}
}
};
MyDialogFragment fragment = MyDialogFragment.newInstance("item");
fragment.setCallback(callback);
fragment.show(ft, MyDialogFragment.TAG);
new MyDialogFragment(callback, item);
fragment.show(getActivity().getSupportFragmentManager(), MyDialogFragment.TAG);
Additionnal source : https://developer.android.com/reference/android/app/DialogFragment
Kotlin Answer
private fun showMyCustomDialog() {
// Show.
MyCustomDialogFragment().show(fm, "MyCustomDialogFragment")
// Set pending transactions.
fm.executePendingTransactions()
// Listen dialog closing.
MyCustomDialogFragment().dialog?.setOnDismissListener {
// You can do you job when it closed.
}
}
Solution using kotlin and additional interface. (an example for a fragment will be shown here, but with a few changes it will work in an activity as well)
First you need to create an interface (the set of parameters can be any):
interface DialogCloseListener {
fun handleDialogClose(dialog: DialogInterface)
}
Then implement this interface in the fragment that calls the DailogFragment:
class YourParentFragment: Fragment(), DialogCloseListener {
override fun handleDialogClose(dialog: DialogInterface) {
// do something
}
}
Now go to your DialogFragment. Implement the onDismiss method. In it, check if the parent fragment implements your interface, call your method, passing the necessary parameters there:
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
if(parentFragment is DialogCloseListener){
(parentFragment as DialogCloseListener).handleDialogClose(dialog)
}
}
I think that this way is good because you can track a specific close event (by passing a certain parameter to the method), for example, canceling an order, and somehow handle it.
Try this
dialog.setOnDismissListener {
Log.e("example","example")
}
Have Fun!
I try to implement a callback from a DialogFragment.
There is a good example, but they don't open this DialogFragment from a Fragment.
http://developer.android.com/guide/topics/ui/dialogs.html#PassingEvents
So here is my code:
public class EditDateDialogFragment extends DialogFragment {
// Use this instance of the interface to deliver action events
EditDateDialogListener mListener;
/* 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 EditDateDialogListener {
public void onDialogPositiveClick(DialogFragment dialog);
public void onDialogNegativeClick(DialogFragment dialog);
}
public static EditDateDialogFragment newInstance( int currentCategoryId ) {
EditDateDialogFragment p = new EditDateDialogFragment();
Bundle args = new Bundle();
args.putInt("currentRecordId", currentCategoryId);
p.setArguments(args);
return p;
}
#Override
public void onCreate(Bundle savedInstanceState) {
mCurrentRecordId = getArguments().getInt("currentRecordId");
super.onCreate(savedInstanceState);
}
public void onAttach(SherlockActivity activity) {
super.onAttach(activity);
try {
// Instantiate the EditDateDialogListener so we can send events to the host
mListener = (EditDateDialogListener) activity;
} catch (ClassCastException e) {
// The activity doesn't implement the interface, throw exception
throw new ClassCastException(activity.toString() + " must implement EditDateDialogListener");
}
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getActivity());
final View v = inflater.inflate(R.layout.fragment_dialog_edit_date, null);
return new AlertDialog.Builder(getActivity()).setTitle("Set Date...").setView(v).setCancelable(true).setPositiveButton("Confirm", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("", "Dialog confirmed");
mListener.onDialogPositiveClick(EditDateDialogFragment.this);
}
}).setNegativeButton("Abort", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("", "Dialog abort");
dialog.cancel();
}
}).create();
}
}
In RecordDetailFragment.java i implement the interface and create a new instance of the EditDateDialogFragment at this way (just the important parts):
public class RecordDetailFragment extends SherlockFragment implements EditDateDialogFragment.EditDateDialogListener {
...
DialogFragment editDateFragment = EditDateDialogFragment.newInstance( recordId );
editDateFragment.show(getActivity().getSupportFragmentManager(), "EditDateDialogFrame");
#Override
public void onDialogPositiveClick(DialogFragment dialog) {
LOGD(TAG, "Overriden Dialog confirmed");
//((EditDateDialogFragment) dialog).mDatePicker;
}
#Override
public void onDialogNegativeClick(DialogFragment dialog) {
// TODO Auto-generated method stub
}
...
}
Now the public void onAttach(SherlockActivity activity) in the EditDateDialogFragment is never called, because I create the DialogFragment from a Fragment instead of an Activity?
How to fix this?
UPDATE:
In the RecordDetailFragment I insert this into the onCreate()
if (savedInstanceState != null) {
EditDateDialogFragment dpf = (EditDateDialogFragment) getActivity().getSupportFragmentManager().findFragmentByTag("EditDateDialogFragment");
if (dpf != null) {
dpf.setListener((EditDateDialogListener) this);
}
}
I changed the instantiation of the DialogFragment to
EditDateDialogFragment editDateFragment = EditDateDialogFragment.newInstance( recordId );
editDateFragment.setListener((EditDateDialogListener) this);
editDateFragment.show(getActivity().getSupportFragmentManager(), "EditDateDialogFragment");
Note the EditDateDialogFragment instead of DialogFragment.
I'm not sure how to update the reference in the dialog.
Just jumped into the same problem, the solution was very simple. Instead of overriding
public void onAttach(Context context) {}
override this:
public void onAttach(Activity activity) {}
Everything is now fine with DialogFragment.
How to fix this?
I'm guessing that you want the RecordDetailFragment instance to behave as the EditDateDialogListener for the DialogFragment. If yes then you need to explicitly set it(and update it) as the listener:
DialogFragment editDateFragment = EditDateDialogFragment.newInstance( recordId );
editDataFragment.setListener(RecordDetailFragment.this);
editDateFragment.show(getActivity().getSupportFragmentManager(), "EditDateDialogFrame");
Where setListener() is a method in the EditDialogFragment like this:
public void setListener(EditDateDialogListener listener) {
mListener = listener;
}
As the user rotates the phone, for example, the Activity along with its fragments will be recreated and you need to re set the listener to point to the newly created RecordDetailFragment instance(you may want to use a WeakReference for mListener). Something similar you can find in this answer(you'll look for the two fragments in the onCreate).
Edit: In the onCreate method of the Activity:
if (savedInstanceState != null) {
RecordDetailFragment df = (RecordDetailFragment) getSupportFragmentManager().findFragmentByTag("rdf"); // "rdf" is the tag used when you add the RecordDetailFragment to the activity
EditDateDialogFragment s = (EditDateDialogFragment) getSupportFragmentManager().findFragmentByTag("tag"); // "tag" is the string set as the tag for the dialog when you show it
if (s != null) {
// the dialog exists so update its listener
s.setListener(df);
}
}
Somewhere in the onCreateDialog cast the mListener to the getActivity():
try {
mListener = (EditDateDialogListener) getActivity();
} catch (Exception e) {
throw new ClassCastException(getActivity().toString()
+ " must implement EditDateDialogListener");
}
A more "modern" approach is to use the new Fragment Result API.
Add a result listener on Fragment A (parent) onCreate:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
childFragmentManager.setFragmentResultListener("requestKey", this) { key, bundle ->
val result = bundle.getString("bundleKey")
}
}
Wherever you need, set result on child Fragment B (on a button click listener, for instance):
button.setOnClickListener {
val result = "resultSample"
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
More info on the docs: https://developer.android.com/guide/fragments/communicate#kotlin