title: Custom dialog interface for multiple Activities/ Fragments
body: <p>I am new to android studio and I am trying implement a dialogfragment to pop up whenever a button is clicked or a toolbar action_add button is clicked. It sends data from the dialog box to a fragment or an activity (trying to understand how it works for both). My dialog class has an interface, which worked great when I implemented it in the fragment, but the activity is a bit different. I am using the interface to pass the data to the activity, then I am using Bundle to transfer the data from the activity to the fragment. I believe the error occurs in the onAttach since I have getTargetFragment(); </p>
  
  <p>Is it possible to have multiple activities/fragments implement a single interface? If so, how do I cater to both the activity and fragment in the interface, onAttach, and the sending of data?   </p>
  
  <p>Thank you guys in advance, below is my code for the custom_dialog class for the dialogbox, and a fragment which is attached to an activity. The goal is either press the button in the fragment or the toolbar on the activity to open a dialog and get an input from the user, that will be transferred to be displayed.</p>
  
  <p>Error:</p>
  
  <pre><code>Process: com.example.andrewg.dialogfragment, PID: 13335
  java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.andrewg.dialogfragment.MyCustomDialog$OnInputSelected.sendInput(java.lang.String)' on a null object reference
      at com.example.andrewg.dialogfragment.MyCustomDialog$2.onClick(MyCustomDialog.java:58)
      at android.view.View.performClick(View.java:6597)
      at android.view.View.performClickInternal(View.java:6574)
      at android.view.View.access$3100(View.java:778)
      at android.view.View$PerformClick.run(View.java:25881)
      at android.os.Handler.handleCallback(Handler.java:873)
      at android.os.Handler.dispatchMessage(Handler.java:99)
      at android.os.Looper.loop(Looper.java:164)
      at android.app.ActivityThread.main(ActivityThread.java:6649)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:826)
  </code></pre>
  
  <p>MainActivity:</p>
  
  <pre><code>public class MainActivity extends AppCompatActivity implements 
  MyCustomDialog.OnInputSelected{
  
  public String dialogInput;
  FragmentManager fragmentManager;
  
  @Override
  public void sendInput(String input) {
      dialogInput = input;
  }
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  
      fragmentManager = getSupportFragmentManager();
  }
  
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      //Inflate the menu, this adds items to the action bar if it is present
      getMenuInflater().inflate(R.menu.menu, menu);
  
      //Redundant
      MenuItem actionMenuItem = menu.findItem(R.id.action_add);
      actionMenuItem.setOnMenuItemClickListener(new 
  MenuItem.OnMenuItemClickListener() {
          @Override
          public boolean onMenuItemClick(MenuItem menuItem) {
              return false;
          }
      });
      return super.onCreateOptionsMenu(menu);
  }
  
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
  
      //Handle action bar clicks here. The action bar will automatically handle clicks on the home/up button
      //so long as you specify a parent activity in AndroidManifest.xml
  
      switch(item.getItemId()){
  
          case R.id.action_add:
              MyCustomDialog dialog = new MyCustomDialog();
              dialog.show(getSupportFragmentManager(), "MyCustomDialog");
  
              //Trying to pass dialog input into an intent to send to the 
  fragment
              /*Intent intent = new Intent(getApplicationContext(), 
  MainFragment.class);
              intent.putExtra("Dialog Input", dialogInput);
              startActivity(intent);*/
              //Trying Bundle to pass data, dialog input between activity and 
  fragment
              Bundle bundle = new Bundle();
              bundle.putString("Dialog Input", dialogInput);
              //Set Fragment class arguments
              MainFragment fragment = new MainFragment();
              fragment.setArguments(bundle); //set argument bundle to fragment
  
              fragmentManager.beginTransaction().replace(R.id.MainFragment,fragment).commit(); //now replace Mainfragment
  
  
              Toast.makeText(this, "Action_Add Clicked Successfully", 
  Toast.LENGTH_SHORT).show();
      }
  
      return super.onOptionsItemSelected(item);
  }
  }
  </code></pre>
  
  <p>MainFragment:</p>
  
  <pre><code>public class MainFragment extends Fragment implements 
  MyCustomDialog.OnInputSelected{
  
  TextView InputDisplay;
  Button OpenDialog;
  
  @Nullable
  @Override
  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_main, container, false);
  
      InputDisplay = view.findViewById(R.id.InputDisplay);
      OpenDialog = view.findViewById(R.id.Open_Dialog);
  
      //Getting Main Activity dialog information with Bundle, that was received from toolbar add
      Bundle bundle = getArguments();
      if(bundle != null){
          String dialogInput = bundle.toString();
          InputDisplay.setText(dialogInput);
      }
      //String dialogInput = this.getArguments().getString("Dialog Input");
  
      OpenDialog.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              Log.d("MainFragment", "onClick: opening dialog");
  
              MyCustomDialog customDialog = new MyCustomDialog();
              customDialog.setTargetFragment(MainFragment.this, 1);
              customDialog.show(getFragmentManager(), "MyCustomDialog");
          }
      });
  
      return view;
  }
  
  @Override
  public void sendInput(String input) {
      InputDisplay.setText(input);
  }
  }
  </code></pre>
  
  <p>Custom Dialog: I added a second interface variable for activity for onAttach to use getActivity(), but it doesn't seem right.</p>
  
  <pre><code>public class MyCustomDialog extends DialogFragment {
  
  private EditText Input;
  private TextView ActionOK, ActionCANCEL;
  
  public OnInputSelected onInputSelected_Fragment;
  public OnInputSelected onInputSelected_Activity;
  
  public interface OnInputSelected{
      void sendInput(String input);
  }
  
  @Override
  public void onAttach(Context context) {
      try{
          onInputSelected_Fragment = (OnInputSelected) getTargetFragment();
          onInputSelected_Activity = (OnInputSelected) getActivity();
      }catch(ClassCastException e){
          Log.e("Custom Dialog", "onAttach: ClassCastException: " + e.getMessage());
      }
      super.onAttach(context);
  }
  
  @Nullable
  @Override
  public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.dialog_my_custom, container, false);
  
      Input = view.findViewById(R.id.Input);
      ActionOK = view.findViewById(R.id.Action_OK);
      ActionCANCEL = view.findViewById(R.id.Action_CANCEL);
  
      ActionCANCEL.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              getDialog().dismiss();
          }
      });
  
      ActionOK.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View view) {
              onInputSelected_Fragment.sendInput(Input.getText().toString());
              onInputSelected_Activity.sendInput(Input.getText().toString());
  
              getDialog().dismiss();
          }
      });
  
      return view;
  }
  }
  </code></pre>