oznecro
oznecro

Reputation: 457

Calling a method in a Fragment from an AlertDialog

Could you please help with the below:

I am trying to call the method deletePlayer inside the fragment PlayersActivityFragment from the alertdialog NameAlertDialogFragment.

The code is below:

    public static class PlayersActivityFragment extends Fragment {

    ArrayList<Player> arrayPlayers;
    ListView listViewPlayers;
    //PlayerAdapter adapter;

    public PlayersActivityFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        arrayPlayers = new ArrayList<Player>();

        View rootView = inflater.inflate(R.layout.fragment_activity_players, container, false);

        Button buttonAddPlayer = (Button) rootView.findViewById(R.id.button_addplayers);
        buttonAddPlayer.setOnClickListener(new View.OnClickListener(){
            public void onClick(View view) {

                arrayPlayers.add(new Player("Player", 0));
                Player selectedPlayer = arrayPlayers.get(arrayPlayers.size()-1);
                ((PlayersActivity)getActivity()).showNameDialogFragment(selectedPlayer);

            }
        });

        listViewPlayers = (ListView) rootView.findViewById(R.id.listView_playername);

        return rootView;

    }

    public void deletePlayer(){
        arrayPlayers.remove(arrayPlayers.size()-1);
    }

}


void showNameDialogFragment(Player player) {
    mDialog = NameAlertDialogFragment.newInstance(player);
    mDialog.show(getFragmentManager(),"SCORE DIALOG");

}

// Class that creates the AlertDialog
public static class NameAlertDialogFragment extends DialogFragment {

    static Player selectedPlayer;

    public static NameAlertDialogFragment newInstance(Player player) {
        selectedPlayer = player;
        return new NameAlertDialogFragment();
    }

    // Build AlertDialog using AlertDialog.Builder
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Get the layout inflater
        LayoutInflater inflater = getActivity().getLayoutInflater();

        final View view = inflater.inflate(R.layout.alertdialog_name, null);

        final EditText editTextName = (EditText) view.findViewById(R.id.edittext_name);

        return new AlertDialog.Builder(getActivity())
                // Inflate and set the layout for the dialog
                // Pass null as the parent view because its going in the dialog layout
                .setView(view)

                .setMessage("Enter Player's Name:")

                //Set up Yes Button
                .setPositiveButton("Done", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, int id) {
                        mName = editTextName.getText().toString().trim();
                        selectedPlayer.setName(mName);
                    }
                })

                .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        //PlayersActivityFragment playersActivityFragment = (PlayersActivityFragment) getFragmentManager().findFragmentById(R.id.container);
                        //playersActivityFragment.deletePlayer();
                        //((PlayersActivityFragment)getTargetFragment()).deletePlayer();
                        NameAlertDialogFragment.this.getDialog().cancel();
                    }
                })

                .create();
    }
}

The two different ways I have tried to call the methods are commented out in the .setNegativeButton onClickListener:

PlayersActivityFragment playersActivityFragment = (PlayersActivityFragment) getFragmentManager().findFragmentById(R.id.container);
playersActivityFragment.deletePlayer();

and

((PlayersActivityFragment)getTargetFragment()).deletePlayer();

Thank you!

Upvotes: 1

Views: 1423

Answers (3)

Kingfisher Phuoc
Kingfisher Phuoc

Reputation: 8190

Actually, I have a little hack, it's not really good, but it's easy to implement: declare PlayersActivityFragment variable in your DialogFragment. Then change your constructor to:

public static NameAlertDialogFragment newInstance(Player player,PlayersActivityFragment fragment ){
 selectedPlayer = player;
 NameAlertDialogFragment test = new NameAlertDialogFragment();
 test.playerActivityFragment = fragment;
 return test;
}

Then you can call playerActivityFragment.deletePlayer() everywhere in your DialogFragment.
P/s: The best way is implement interface, but for lazy coder like me, the method above is better lol!

Upvotes: 0

oznecro
oznecro

Reputation: 457

I am not sure if this is the correct way of doing things, but I have come to a working solution.

First I moved ArrayList<Player> arrayPlayers; outside of the PlayersActivityFragment fragment.

Then I moved the method:

public void deletePlayer(){
    arrayPlayers.remove(arrayPlayers.size()-1);
}

outside of the PlayersActivityFragment fragment.

I then called the deletePlayer() method inside the alertdialog with the line ((PlayersActivity)getActivity()).deletePlayer();.

Upvotes: 0

MidasLefko
MidasLefko

Reputation: 4549

First of all, why are all of your classes static? Anyway, here's an answer that should work...

Try using an interface as a callback. For example:

First create an interface.

public interface NameAlertDialogListener {
    public void onNegativeClick();
} 

Then have PlayersFragment implement NameAlertDialogListener.

public static class PlayersActivityFragment extends Fragment implements  NameAlertDialogListener

Next, in the PlayersFragment, create a method called onNegativeClick.

@Override
public void onNegativeClick()  {
    //delete or whatever you want to do.
} 

Create a member variable for the listener:

static Player selectedPlayer;
static NameAlertDialogListener mCallBack;

Next create a method in the dialog fragment called setListener.

public void setListener(NameAlertDialogListener callback) { 
    try { 
        mCallBack = callback; 
    } catch (ClassCastException e){ 
        throw new ClassCastException(callback.toString() + " must implement NameAlertDialogListener" ); 
    } 
}

Then, when you create the dialog fragment call the setListener method.

void showNameDialogFragment(Player player) { 
    mDialog = NameAlertDialogFragment.newInstance(player);
    mDialog.setListener(this);
    mDialog.show(getFragmentManager(),"SCORE DIALOG"); 
}

Lastly, in your negative click listener:

.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { 
public void onClick(DialogInterface dialog, int id) {
        mCallBack.onNegativeClick() ;
        NameAlertDialogFragment.this.getDialog().cancel(); 
    } 
})

Upvotes: 1

Related Questions