Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

A Somewhat Complicated Question On Passing Data...

Hello.

I'm going to try to explain this as best as I can: I have three classes:

1 - My Main Activity. 2 - A DialogFragment. 3 - A ListAdapter/ViewHolder.

Now the scenario here is that I have a button in my ViewHolder that opens the DialogFragment in my MainActivity. The DialogFragment has two buttons, the first one dismisses the Dialog, which I got working, the second one removes the item from the list. Of course, the button for removing the item gives me an error because it doesn't know what item in the list I want removed. I'm puzzled because I'm having trouble how to retrieve the position of the item in the list when the code for the button, in the ViewHolder, that opens the DialogFragment is in the MainActivity, and I want the data to be passed to the DialogFragment.

Here is my code for the code in the MainActivity:

@Override
    public void onItemClicked(View v) {
        PromptDeleteDialogFragment fragment = new PromptDeleteDialogFragment();
        fragment.show(getFragmentManager(), PROMPT_FRAGMENT);
    }

DialogFragment:

public interface ConfirmDeleteClickListener {
        void confirmDeleteListener(View v);
    }

    public PromptDeleteDialogFragment() {}

    private TextView mYesTextView;
    private TextView mNoTextView;
    private TextView mPromptTextView;
    private ConfirmDeleteClickListener mListener;

Context context = getActivity();
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
        View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fragment_prompt, null);
        builder.setView(view);

        mYesTextView = (TextView) view.findViewById(R.id.yesTextView);
        mNoTextView = (TextView) view.findViewById(R.id.noTextView);
        mPromptTextView = (TextView) view.findViewById(R.id.promptTextView);

        mPromptTextView.setText("Would you like to delete...");

        mYesTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mListener.confirmDeleteListener(v);
            }
        });

        mNoTextView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismiss();
            }
        });

        AlertDialog dialog = builder.create();
        dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        return dialog;

And ViewHolder:

public interface OnItemClickListener {
        void onItemClicked(View v);
    }

public class ViewHolder extends RecyclerView.ViewHolder implements PromptDeleteDialogFragment.ConfirmDeleteClickListener {

        public ImageView mDeleteItemImage;

        public ViewHolder(View itemView) {
            super(itemView);

            mDeleteItemImage = (ImageView) itemView.findViewById(R.id.deleteImage);

            mDeleteItemImage.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mListener.onItemClicked(v);
                }
            });
        }

        public void bindHolder(ListItem item) {
            mCheckBox.setText(item.getAssignment());
        }

        @Override
        public void confirmDeleteListener(View v) {
        }
    }

1 Answer

Kourosh Raeen
Kourosh Raeen
23,733 Points

You can add another parameter to the onItemClicked for position of an item in the list:

public interface OnItemClickListener {
    void onItemClicked(View v, int position);
}

Then in your ViewHolder use the getAdapterPosition() method to get the position of the item clicked as an argument passed to onItemClicked:

mDeleteItemImage.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        mListener.onItemClicked(v, getAdapterPosition());
    }
});

Then in MainActivity fix the definition of onItemClicked accordingly:

@Override
public void onItemClicked(View v, int position) {
    PromptDeleteDialogFragment fragment = new PromptDeleteDialogFragment();
    fragment.show(getFragmentManager(), PROMPT_FRAGMENT);
}

You may want to do the deleting right in your MainActivity. If you have your data items in an ArrayList you can call remove(position) on it and then call notifyDataSetChanged() on the adapter.

Whether the item gets removed from the list is defined by the DialogFragment. In the function (Which is defined in PromptDeleteDialogFragment that the onItemClicked() function opened):

@Override
        public void confirmDeleteListener(View v) {
        }

I want to retrieve the position of the item that was clicked then delete it using an OnClickListener.

Kourosh Raeen
Kourosh Raeen
23,733 Points

Sure, but the actual removal can happen in MainActivity. You can have MainActivity implement ConfirmDeleteClickListener, then override confirmDeleteListener in MainActivity where you remove the item at position position from your list or adapter and then call notifyDataSetChanged() on the adapter. This way you don't need to pass position to your DialogFragment and then again from the DialogFragment back to the ViewHolder. Then in the DialogFragment if the user presses the Yes button you just call confirmDeleteListener() and it wouldn't need to pass any data back to MainActivity.

Okay, but because onItemClicked() and confirmDeleteListener() are two different functions and onItemClicked() has the position parameter, how would I retrieve the position then implement it into my confirmDeleteListener()?

Kourosh Raeen
Kourosh Raeen
23,733 Points

One way would be to declare a class variable in MainActivity, say:

private int mPosition;

Then you set it in onItemClicked:

@Override
public void onItemClicked(View v, int position) {
    mPosition = position;
    PromptDeleteDialogFragment fragment = new PromptDeleteDialogFragment();
    fragment.show(getFragmentManager(), PROMPT_FRAGMENT);
}

Now, mPosition is available in confirmDeleteListener.

It's working, thank you!

Kourosh Raeen
Kourosh Raeen
23,733 Points

Awesome! Glad I could help!