2

I have a Fragment (FragmentColourSets) which shows a RecyclerView. I want to be able to click on an item in the RecyclerView, and to then see a DialogFragment showing information on that item. I expected there to be an OnClickListener in the RecyclerView which would handle this, but I now see that there isn't, and I'm stuck. Solutions I've found have involved adding a click listener in the Adapter, but from there I can't access the FragmentManager or Context in order to show the DialogFragment.

So, the relevant part of the FragmentColourSets layout is as follows:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_colour_sets"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

The FragmentColourSets class is (I've left out some irrelevant stuff to keep it shorter):

public class FragmentColourSets extends Fragment {

    private ArrayList<ColourSet> mColourSets;
    private Context             mContext;
    private FirebaseFirestore   mDb;
    private RecyclerView        mRVColourSets;
    private String              mUid;

    private FragmentManager     mFragmentManager;

    static public FragmentCurrentColourSets newInstance(Context context, ArrayList<ColourSet> colourSets) {

        FragmentCurrentColourSets f = new FragmentColourSets();
        f.setRequiredData(context, colourSets);

        return f;
    }

    public void setRequiredData(Context context, ArrayList<ColourSet> colourSets) {

        this.mContext = context;
        this.mCurrentColourSets = colourSets;

    }

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

        // Inflate layout
        View rootView = inflater.inflate(R.layout.fragment_colour_sets, container, false);

        mRVColourSets = rootView.findViewById(R.id.rv_colour_sets);

        mFragmentManager = getChildFragmentManager();

        // Set up Layout Manager, and set Recycler View to use it
        LinearLayoutManager mManager = new LinearLayoutManager(getActivity());
        mManager.setReverseLayout(true);
        mManager.setStackFromEnd(true);
        mRVColourSets.setLayoutManager(mManager);

        return rootView;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        mContext = getActivity();

    }

    // Set colour sets to be shown
    public void setColourSets(ArrayList<ColourSet> coloursets) {
        mColourSets = coloursets;
        fillView();
    }

    public void setUid(String thisUid) { mUid = thisUid; }

    public void setDb(FirebaseFirestore db) { mDb = db; }

    /**
     * fillView
     * List current Colour Sets in recycler view
     * This takes the colour sets and shows them
     **/
    private void fillView() {

        if(mRVColourSets == null)   return;
        if(mColourSets == null) return;

        AdapterListColourSets mAdapter = new AdapterListColourSets(mColourSets);

        mRVColourSets.setAdapter(mAdapter);

    }

}

AdapterListColourSets is:

public class AdapterListColourSets extends RecyclerView.Adapter<AdapterListColourSets.ViewHolderColourSet> {

        private ArrayList<ColourSet>    colourSets;

        public AdapterListColourSets(ArrayList<ColourSet> colourSets) {
            this.colourSets=colourSets;
        }

        @NonNull
        @Override
        public ViewHolderColourSet onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

            View layoutColourSets = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_colour_set, null);
            return new ViewHolderColourSet(layoutColourSets);
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolderColourSet holder, int position) {
            holder.colourSetName.setText(colourSets.get(position).getName());

        }

        @Override
        public int getItemCount() {
            return colourSets.size();
        }

        class ViewHolderColourSet extends RecyclerView.ViewHolder {

            TextView colourSetName, colourSetKey;

            ViewHolderColourSet(View itemView) {
                super(itemView);

                colourSetName = itemView.findViewById(R.id.tv_colour_set_name);
                colourSetKey = itemView.findViewById(R.id.tv_colour_set_key);

            }
        }
    }

So, at some point I need to attach an OnClick listener to each item shown in the RecyclerView, so that I can do something like this:

private void onClick() {

    DFEditColourSet dfEdit 
           = DFEditColourSet.newInstance(mContext);
    dfEdit.show(mFragmentManager, "Edit Colour Set");
}

However, within the adapter I don't have access to the Context or to the FragmentManager. How should I be doing this?

Sharon
  • 3,471
  • 13
  • 60
  • 93

1 Answers1

1

There are a lot of resources out there that show you how this can be done. Take a look at this blog post. Regarding your question of the context not being available in your adapter: just pass it in as a constructor argument. This can be seen in this example repository.

Sharing the data between the two fragments could be done using a SharedViewModel

If you can't figure it out, feel free to ask more questions.

EDIT I also found this answer to a similar question, which might offer a solution that is more easy to implement than the blog post I mentioned.

Tomirio
  • 149
  • 3
  • 12
  • Thank you! Don't know why I didn't manage to find a few examples online myself; they just didn't show up when I searched! Also don't know why I didn't think to pass the context in... this is why I shouldn't code when I'm tired! – Sharon Apr 12 '19 at 12:51