1

I tried to implement OnItemClickListener in Fragment with RecycleView Adapter, but my code seems not to work well, OnItemClickListener keeps turning red when I try to change it to getContext(). I've tried to find many ways to get it done, but that makes me find another error in my code. . your help will make my day brighter,

public class MountainFragment extends Fragment {

private final int LOCATION_SIZE = 10;
private final int LOCATION_TYPE = 1;

public MountainFragment() {
    // Required empty public constructor
}

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

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

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

    String name, imageName, address;
    Drawable image;
    int resourceId, imageId;

    final ArrayList<WorldDataModel> mountainArrays = new ArrayList<WorldDataModel>();
    for (int n = 1; n <= LOCATION_SIZE; n++) {
        //get Location Name
        resourceId = getResources().getIdentifier("location_name_" + LOCATION_TYPE
                + "_" + n, "string", getActivity().getPackageName());
        name = getResources().getString(resourceId);

        //get address
        resourceId = getResources().getIdentifier("location_address_" + LOCATION_TYPE
                + "_" + n, "string", getActivity().getPackageName());
        address = getResources().getString(resourceId);

        //get image thumbnail
        resourceId = getResources().getIdentifier("location_thumbnail_" + LOCATION_TYPE
                + "_" + n, "string", getActivity().getPackageName());
        imageName = getResources().getString(resourceId);
        imageId = getResources().getIdentifier(imageName, "drawable", getActivity().getPackageName());
        image = getResources().getDrawable(imageId);

        //add new data to list
        mountainArrays.add(new WorldDataModel(name, address, image));
    }

    // using simple recycle view
    RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.word_list_activity);
    recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
    RecycleViewWorldAdapter adapter = new RecycleViewWorldAdapter(mountainArrays);
    recyclerView.setAdapter(adapter);

    //on list item click
    recyclerView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            WorldDataModel worldDataModel = mountainArrays.get(position);
            Intent intent = new Intent(getActivity(), DetailsActivity.class);
            intent.putExtra("category", LOCATION_TYPE);
            intent.putExtra("location", position + 1);
            getActivity().startActivity(intent);
        }
    });

    // Inflate the layout for this fragment
    return rootView;
}

and here's my adapter class

package com.example.mytourguideapp;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;

public class RecycleViewWorldAdapter extends RecyclerView.Adapter<RecycleViewWorldAdapter.MyViewHolder> {

    private ArrayList<WorldDataModel> worldDataModelArrayList;

    public class MyViewHolder extends RecyclerView.ViewHolder {

        public TextView textViewLocationName, textViewPlacesName;
        public ImageView imageOnCard;

        public MyViewHolder(View itemView) {
            super(itemView);
            textViewLocationName = (TextView) itemView.findViewById(R.id.location_name);
            textViewPlacesName = (TextView) itemView.findViewById(R.id.places_name);
            imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);

        }
    }

    public RecycleViewWorldAdapter(ArrayList<WorldDataModel> worldDataModelArrayList) {
        this.worldDataModelArrayList = worldDataModelArrayList;
    }

    @Override
    public MyViewHolder onCreateViewHolder( ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_item_layout, parent, false);

        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(RecycleViewWorldAdapter.MyViewHolder holder, int position) {
        WorldDataModel worldDataModel = worldDataModelArrayList.get(position);
        holder.textViewPlacesName.setText(worldDataModel.getName());
        holder.textViewLocationName.setText(worldDataModel.getAddress());
        holder.imageOnCard.setImageDrawable(worldDataModel.getImageThumbnail());

    }

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

}
tankian vei
  • 27
  • 1
  • 5
  • Does this answer your question? [Why doesn't RecyclerView have onItemClickListener()?](https://stackoverflow.com/questions/24885223/why-doesnt-recyclerview-have-onitemclicklistener) – Nitish Nov 08 '21 at 07:44
  • yes, it was, but I didn't understand how to implement it, :') – tankian vei Nov 08 '21 at 08:00
  • Recycler view doesn't have it's own click listener . You need to set click listener on it's view. Set click listener on layout used in it's adapter `list_item_layout` , might be some button or parent layout – Nitish Nov 08 '21 at 08:33
  • I have written the answer using your code ,hope it helps you understand how it's implement – Nitish Nov 08 '21 at 08:54

1 Answers1

1

You can send the callback from your Adapter class to your fragment/activity.

  1. First create a interface class

    public interface OnItemClickListener {
         void onItemClick(WorldDataModel item,int position);
     }
    
  2. Next modify your Adapter class , in your case RecycleViewWorldAdapter

    i) Send listener as a parameter in your constructor

    private final OnItemClickListener listener;
    public RecycleViewWorldAdapter(ArrayList<WorldDataModel> worldDataModelArrayList,  OnItemClickListener listener) {
             this.worldDataModelArrayList = worldDataModelArrayList;
             this.listener = listener;
         }
    

    ii) Set onCLick listener on some view in your ViewHolder class

    public MyViewHolder(View itemView) {
             super(itemView);
             textViewLocationName = (TextView) itemView.findViewById(R.id.location_name);
             textViewPlacesName = (TextView) itemView.findViewById(R.id.places_name);
             imageOnCard = (ImageView) itemView.findViewById(R.id.image_on_cardview);
             // change your listener on any other view if you want
             imageOnCard..setOnClickListener(new View.OnClickListener() {
                     @Override public void onClick(View v) {
                           listener.onItemClick(worldDataModelArrayList.get(getAdapterPosition()),getAdapterPosition());
                     }
            });
    
         }
    
  3. Now modify your Activity/Fragment class to listen to your interface callback , in your case MountainFragment in onCreateView

     // using simple recycle view
     RecyclerView recyclerView = (RecyclerView) rootView.findViewById(R.id.word_list_activity);
     recyclerView.setLayoutManager(new LinearLayoutManager(this.getContext()));
     RecycleViewWorldAdapter adapter = new RecycleViewWorldAdapter(mountainArrays,new RecycleViewWorldAdapter.OnItemClickListener() {
         @Override public void onItemClick(WorldDataModel item, int position) {
            // implement click listener as per your requirement
         WorldDataModel worldDataModel = item;
         Intent intent = new Intent(getActivity(), DetailsActivity.class);
         intent.putExtra("category", LOCATION_TYPE);
         intent.putExtra("location", position + 1);
         getActivity().startActivity(intent);
    
         });
     recyclerView.setAdapter(adapter);
    
Nitish
  • 3,075
  • 3
  • 13
  • 28
  • It works well, but I can't get a reference on `position + 1`, when I clicked the item, my `putExtra` didn't show the correct data into detailsActivity. here's the code [link](https://github.com/zhavei/MyTourGuideApp/blob/50cbdfe32b8812d25cd49e0214c6f0e59a932cf9/app/src/main/java/com/example/mytourguideapp/DetailsActivity.java) – tankian vei Nov 08 '21 at 15:20
  • 1
    Pass one more parameter in the interface callback, `postion` from the adapter. This way you can be `position + 1` in your fragment class. Also in your adapter class you don't need to set click listener on `textViewLocationName` , `textViewPlacesName` and `imageOnCard`, you can set in your parent , `card view` or `linear layout` – Nitish Nov 09 '21 at 04:52
  • I'm trying to work hard on this, but still, get an error, would you mind checking my answer again below, – tankian vei Nov 09 '21 at 08:05
  • 1
    I have edited my answer to pass position also as a parameter , please check – Nitish Nov 09 '21 at 09:45
  • It works perfectly. I am so thankful for the time you took to help with my difficulties. You're a wonderful person. – tankian vei Nov 09 '21 at 14:08
  • 1
    Glad I could be of help – Nitish Nov 09 '21 at 14:55