Nested RecyclerView OnclickListener [closed]

109
May 08, 2022, at 10:00 AM
Closed. This question needs details or clarity. It is not currently accepting answers.

Want to improve this question? Add details and clarify the problem by editing this post.

Closed 3 months ago.

Improve this question

I have nested RecyclerView (MainRecyclerview and ChildRecyclerview) with two Adapters(MainRecyclerviewAdapter and ChildRecyclerviewAdapter), i create an interface to handle click for childRecyclerview, but i can only access that click in MainRecyclerviewAdapter. I want to know how to handle click for items in childRecyclerview in MainActivity, thanks.

Here is my code:

//MainActivity

public class MainActivity extends AppCompatActivity {

List<Section> sectionList = new ArrayList<>();
RecyclerView mainRecyclerView;
LinearLayoutManager layoutManager;
MainRecyclerAdapter mainRecyclerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_profile_properties);
    initData();
    initRecyclerView();

}

}

//ChildRecyclerAdapter

public class ChildRecyclerAdapter extends RecyclerView.Adapter<ChildRecyclerAdapter.ChildViewHolder> {

private final List<String> items;
private OnItemClickListener mListener;
public ChildRecyclerAdapter(List<String> items) {
    this.items = items;
}
public void setOnItemClickListener(OnItemClickListener listener) {
    mListener = listener;
}
@NonNull
@Override
public ChildViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_row, parent, false);
    return new ChildViewHolder(view, mListener);
}
@Override
public void onBindViewHolder(@NonNull ChildViewHolder holder, int position) {
    holder.itemTextView.setText(items.get(position));
}
@Override
public int getItemCount() {
    return items.size();
}

public class ChildViewHolder extends RecyclerView.ViewHolder {
    TextView itemTextView;
    ChildViewHolder(final View itemView, OnItemClickListener listener) {
        super(itemView);
        itemTextView = itemView.findViewById(R.id.txt_item_view);
        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (listener != null) {
                    int position = getBindingAdapterPosition();
                    if (position != RecyclerView.NO_POSITION) {
                        String item = items.get(position);
                        listener.onItemClick(item);
                    }
                }
            }
        });
    }
}

}

//MainRecyclerAdapter

public class MainRecyclerAdapter extends RecyclerView.Adapter<MainRecyclerAdapter.MainViewHolder> {

List<Section> sectionList;
public MainRecyclerAdapter(List<Section> sectionList) {
    this.sectionList = sectionList;
}
@NonNull
@Override
public MainViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());
    View view = inflater.inflate(R.layout.section_row, parent, false);
    return new MainViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull MainViewHolder holder, int position) {
    Section section = sectionList.get(position);
    String sectionName = section.getSectionName();
    List<String> items = section.getSectionItems();
    holder.sectionNameTextView.setText(sectionName);
    ChildRecyclerAdapter childRecyclerAdapter = new ChildRecyclerAdapter(items);
    holder.recyclerChild.setAdapter(childRecyclerAdapter);
    childRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() {
        @Override
        public void onItemClick(String item) {
            // TODO: 07/02/2022 handle click
        }
    });
}
@Override
public int getItemCount() {
    return sectionList.size();
}

public static class MainViewHolder extends RecyclerView.ViewHolder {
    TextView sectionNameTextView;
    RecyclerView recyclerChild;
    public MainViewHolder(final View itemView) {
        super(itemView);
        sectionNameTextView = itemView.findViewById(R.id.txt_section_name);
        recyclerChild = itemView.findViewById(R.id.child_recyclerview);
        LinearLayoutManager layoutManager = new LinearLayoutManager(itemView.getContext());
        recyclerChild.setLayoutManager(layoutManager);
    }
}

}

//OnItemClickListener

public interface OnItemClickListener {

void onItemClick(String item);

}

Answer 1

You can simple make one more interface and call it in nested adapter's onclick method.

So it will pass that data from adapter to the activity when you click any adapter items.

Like this :

1. Create an interface for getting the child recyclerview item click in the activity or fragment.

First, you need to change your child adapter's click listener from this

public interface OnItemClickListener {
    void onItemClick(String item);
}

to this :

public interface OnItemClickListener {
    void onItemClick(int childPosition);
}

then pass the adapter position of child recyclerview instead of string value.

Now, make a new interface to get both the parent and child item clicks in the activity or fragment.

public interface RvItemClickListener {
    void onChildItemClick(int parentPosition, int childPosition, String item);
}

2. Define the listener and call it on child item click in parent recyclerview adapter :

RvItemClickListener rvItemClickListener;
    
public void setRvItemClickListener(RvItemClickListener rvItemClickListener){
    this.rvItemClickListener = rvItemClickListener;
}

3. Call it on child item click :

childRecyclerAdapter.setOnItemClickListener(new OnItemClickListener() {
                @Override
                public void onItemClick(int childPosition) {
                    String item = items.get(childPosition);
                    rvItemClickListener.onChildItemClick(getAdapterPosition(), childPosition, item);
                  }
               });

4. The last step is to override the method in your activity or fragment as you do it normally :

@Override
public void onItemClick(int parentPosition, int childPosition, String item) {
}

I hope it's enough for you to understand what I am trying to say.

It's just an example. Do make changes as per your needs.

Answer 2

I would recommend you to avoid nesting recycler views. You can add different views to an adapter to differtiate between different views in a single recycler view

class RecyclerViewAdapter(context: Context, list: ArrayList<Data>) :
    RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    companion object {
        const val VIEW_TYPE_ONE = 1
        const val VIEW_TYPE_TWO = 2
    }
    private val context: Context = context
    var list: ArrayList<Data> = list
    private inner class View1ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var message: TextView = itemView.findViewById(R.id.textView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            message.text = recyclerViewModel.textData
        }
    }
    private inner class View2ViewHolder(itemView: View) :
        RecyclerView.ViewHolder(itemView) {
        var message: TextView = itemView.findViewById(R.id.textView)
        fun bind(position: Int) {
            val recyclerViewModel = list[position]
            message.text = recyclerViewModel.textData
        }
    }
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        if (viewType == VIEW_TYPE_ONE) {
            return View1ViewHolder(
                LayoutInflater.from(context).inflate(R.layout.item_view_1, parent, false)
            )
        }
        return View2ViewHolder(
            LayoutInflater.from(context).inflate(R.layout.item_view_2, parent, false)
        )
    }
    override fun getItemCount(): Int {
        return list.size
    }
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (list[position].viewType === VIEW_TYPE_ONE) {
            (holder as View1ViewHolder).bind(position)
        } else {
            (holder as View2ViewHolder).bind(position)
        }
    }
    override fun getItemViewType(position: Int): Int {
        return list[position].viewType
    }
}

This makes it a lot easier to manipulate the click listeneres and to test the code as well

Rent Charter Buses Company
READ ALSO
Getting IMEI number using ADB commands Android 12

Getting IMEI number using ADB commands Android 12

For android versions before 11 I was using the below command to get IMEI number from my device:

194
Stopping Exoplayer on swiping in viewPager

Stopping Exoplayer on swiping in viewPager

I am making a reels type appI have made a ReelsFragment and ReelsAdapter

172
Weird White lines in Android Launcher?

Weird White lines in Android Launcher?

I'm currently programming and I noticed that there are strange white lines around the app in the Android LauncherWith other apps, everything is normal

110
Android, Microsoft Graph API - network unreachable

Android, Microsoft Graph API - network unreachable

I have followed the example at https://docsmicrosoft

188