Search code examples
androidandroid-fragmentsandroid-dialogfragmentandroid-lifecycle

Multiple DialogFragment event callbacks - how do I tell which fragment to update?


Here is my situation. I have a fragment which has two buttons on it. When you tap on either button, a DialogFragment appears which contains a single EditText with ok/cancel buttons. Both buttons open the same DialogFragment, but the data input into the EditTexts needs to be kept separate.

I recently started implementing the fragment event callback pattern from the Android docs seen here, but have run into an issue - I have two buttons using the same event callback and am not sure how to differentiate which one the user has just finished using. So using the docs as an example, I can open FragmentA from two buttons on the same screen, but need to handle the result differently depending on which button I clicked.

In my fragment:

public static class FragmentA extends DialogFragment {
  public interface OnEditNameListener {
    public void onPositiveButtonClicked(String newName);
  }
}

@Override
public void onAttach(Context context){
    super.onAttach(context);
    try {
        mListener = (OnEditNameListener ) context;
    }
    catch (ClassCastException e) {
        throw new ClassCastException(context.toString() + " must implement OnEditNameListener ");
    }
}

In my Activity, which implements the OnEditNameListener:

button1.setOnClickListener(new OnClickListener(){
  @Override
  public void onClick(View view) {
    (new EditNameDialog.Builder())
      .setTitle(getContext().getString(R.string.title))
      .setValue(currentText)
      .show(mParentFragmentActivity.getSupportFragmentManager());
       }
    });

button2.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick(View view) {
    (new EditNameDialog.Builder())
      .setTitle(getContext().getString(R.string.title2))
      .setValue(currentText2)
      .setInputType(InputType.TYPE_CLASS_NUMBER)
      .show(mParentFragmentActivity.getSupportFragmentManager());
      }
  });

@Override
public void onPositiveButtonClicked(String newName) {
  ... //does stuff with the name. 
//Currently no way to determine whether this came from button1 or button2.
}

Currently, both callbacks hit the same OnPositiveButtonClicked method with the input from the DialogFragment, but I do not know how to determine which of the two buttons this came from.


Solution

  • First of all you have to add an argument to your onPositiveButtonClicked(String name,int buttonId),and the pass to FragmentA an argument based on the button pressed like:

    FragmentA fragment=new FragmentA();
     Bundle args = new Bundle();
     args.putInt("buttonId", 1 or 2);
     fragment.setArguments(args);
    //open the fragment from the activity
    

    Then in your FragmentA onCreate method try:

     int buttonId = getArguments().getInt("buttonId"); 
    

    and finally when positive button pressed call:

    onPositiveButtonClicked(newName,buttonId)
    

    UPDATE

    An even better solution is to create a setter in your DialogFragment and use anonymus interfaces like:

    (new EditNameDialog.Builder())
          .setTitle(getContext().getString(R.string.title))
          .setValue(currentText).setOnEditNameListener(new EditNameListener{
             @Override
              onPositiveButtonClicked(String newName){
              //handle action
              }
    });
    

    And in your DialogFragment add the setter:

    EditNameListener listener;
    public DialogFragment setOnEditNameListener(EditNameListener listener){
       this.listener=listener;
     return this;
    }