My app's MainActivity has a ViewPager which has three children(swipe views). When swiped to last child, the ActionBar gets two menu items. On clicking one item, a Dialog pops up to add a name of an item into a Database. On clicking second menu item, another Dialog pops up that prompts user to enter the name of the item that is to be removed from the Database. These Dialogs are getting constructed by separate Dialog Fragments. Basically what I want is to get the callback event from the Dialog that the positive or negative button has been clicked and wanna perform some action in the fragment which is as I mentioned is the last child of my ViewPager. I've seen the Android documentation as well as a Youtube video to learn how to implement the interface, yet my app's crashing.
Here's the code for my DialogFragment which shows a Dialog that prompts the user to enter input and save it to the Database.
package com.example.android.mybusiness;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class AddCigaretteNameDialog extends DialogFragment {
    EditText userInput;
    String cigaretteName;
    DbHelper dbHelper;
    public AddCigaretteNameDialogListener listener;
    public interface AddCigaretteNameDialogListener {
        void onDialogPositiveClick(String name);
    }
    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        dbHelper = new DbHelper(getContext());
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        // SET THE TITLE FOR THE DIALOG.
        builder.setTitle(R.string.add_title);
        // GET THE LAYOUT INFLATOR
        LayoutInflater inflater = getActivity().getLayoutInflater();
        // INFLATE THE LAYOUT AND PUT IT INTO A VARIABLE.
        // PASS NULL AS PARENT VIEW, BECAUSE IT'S GOING IN THE DIALOG
        View view = inflater.inflate(R.layout.edit_text_for_dialogs, null);
        // GET THE EDIT_TEXT FROM THE 'VIEW' VARIABLE.
        userInput = view.findViewById(R.id.cigarette_name_user_input);
        // SET THE LAYOUT FOR THE DIALOG
        builder.setView(view);
        // SET ACTION BUTTONS
            builder.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    // GET THE USER INPUT FROM THE EDIT_TEXT ABOVE AND PUT IT INTO A VARIABLE.
                    cigaretteName = userInput.getText().toString();
                    // PUT THE USER INPUT IN THE DATABASE.
                    Boolean result = dbHelper.insertCigaretteName(cigaretteName);
                    if (result) {
                        // SHOW SUCCESS MESSAGE THAT CIGARETTE NAME HAS BEEN INSERTED.
                        Toast.makeText(getContext(), cigaretteName + " has been added successfully!", Toast.LENGTH_SHORT).show();
                        listener.onDialogPositiveClick(cigaretteName);
                    } else {Toast.makeText(getContext(), "Something is wrong", Toast.LENGTH_SHORT).show();}
                }
            })
            .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dismiss();
                }
            });
        // RETURN THE DIALOG.
        return builder.create();
    }
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        // VERIFY THAT THE HOST ACTIVITY IMPLEMENTS THE CALLBACK INTERFACE
        try {
            listener = (AddCigaretteNameDialogListener) getTargetFragment();
        } catch (ClassCastException e){
            // THE ACTIVITY DOESN'T IMPLEMENT INTERFACE, THROW AN EXCEPTION.
            throw new ClassCastException(getActivity().toString() + " must implement listener");
        }
    }
}
And here's the fragment which is the last child of the view pager.
package com.example.android.mybusiness;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
/**
 * A simple {@link Fragment} subclass.
 */
public class Purchase extends Fragment implements AddCigaretteNameDialog.AddCigaretteNameDialogListener {
    Spinner spinner;
    DbHelper dbHelper;
    ArrayAdapter<String> arrayAdapter;
    // FRAGMENT'S CONSTRUCTOR.
    public Purchase() { }
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // KIND OF REQUIREMENT FOR OPTION MENUS.
        setHasOptionsMenu(true);
        // INSTANTIATING THE OBJECT TO RUN A FUNCTION, WHICH GETS THE CIGARETTES NAME.
        dbHelper = new DbHelper(getContext());
        // Inflate the layout for this fragment
        // AND PUT IT INTO A VARIABLE SO WIDGETS CAN BE ACCESSED.
        View view = inflater.inflate(R.layout.fragment_purchase, container, false);
        // FIND THE spinner.
        spinner = view.findViewById(R.id.spinner);
        // CREATING THIS ADAPTER TO POPULATE THE SPINNER WIDGET.
        arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, dbHelper.getAllCigaretteNames());
        // SETTING THE ADAPTER TO THE SPINNER, WHICH WILL PROVIDE THE CONTENT TO BE SELECTED BY ME.
        spinner.setAdapter(arrayAdapter);
        return view;
    }
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.add_cigarette:
                AddCigaretteNameDialog addCigaretteNameDialog = new AddCigaretteNameDialog();
                addCigaretteNameDialog.show(getFragmentManager(), "add_cigarette_name");
                return true;
            case R.id.remove_cigarette:
                RemoveCigaretteNameDailog RemoveCigaretteNameDailog = new RemoveCigaretteNameDailog();
                RemoveCigaretteNameDailog.show(getFragmentManager(), "add_cigarette_name");
            ;    return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    @Override
    public void onDialogPositiveClick(String name) {
        arrayAdapter.add(name);
    }
}
Here's the crash log:
12-07 13:13:59.278 25327-25327/com.example.android.mybusiness E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.android.mybusiness, PID: 25327 java.lang.NullPointerException: Attempt to invoke interface method 'void com.example.android.mybusiness.AddCigaretteNameDialog$AddCigaretteNameDialogListener.onDialogPositiveClick(java.lang.String)' on a null object reference at com.example.android.mybusiness.AddCigaretteNameDialog$2.onClick(AddCigaretteNameDialog.java:58) at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5296) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
Line 58 is
listener.onDialogPositiveClick(cigaretteName);
Thanks in advance!
 
     
    