Reputation: 89
I have 5 row to display in RecyclerView. When user clicks to one of the items, another activity opens. Each item has starts different activity. I handled the click event like below.
switch (getAdapterPosition()) {
case 1:
ActivityUtil.startActivity(itemView.getContext(), BlablaActivity.class);
break;
//other cases
}
It works correctly. But what if a new item is added to the list in the future? For every single item, I have to add a new case to the switch-case. This is not a proper solution according to Open Closed Principle. How should I handle it? Any suggestions would be great...
Upvotes: 1
Views: 159
Reputation: 54224
Ideally, you would add a Class<? extends Activity>
field to the class that represents your RecyclerView items. Then you could simply access this field in your click listener (this code would be inside onCreateViewHolder()
):
holder.itemView.setOnClickListener(v -> {
int position = holder.getAdapterPosition();
if (position != RecyclerView.NO_POSITION) {
Class<? extends Activity> activityClass = items.get(position).getActivityClass();
ActivityUtil.startActivity(v.getContext(), activityClass);
}
});
This way, each item is responsible for knowing where to go when it is clicked. You can add new items to your list without ever having to touch the adapter code.
Upvotes: 1
Reputation: 29794
It can be handled easily if you're strictly making the RecyclerView adapter working as a view only, i.e only showing the data with the view. All the logic decision responsibility should be delegate back to the parent activity or fragment. This can be achieved by using a Callback/Listener.
Whenever there is a click event in the RecyclerView item, tell the parent activity or fragment to handle it.
You need to change your adapter to something like this:
public class YourAdapter extends RecyclerView.Adapter<YourAdapter.ViewHolder> {
// Local variable for listener
private OnItemClickListener listener;
// Listener interface
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
}
// set the listener on parent activity or fragment
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
....
public ViewHolder(final View itemView) {
super(itemView);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (listener != null) return;
// tell the parent to handle the item.
listener.onItemClick(itemView, position);
}
});
}
}
}
Then you can use the following to handle the click:
// assuming adapter is your adapter
adapter.setOnItemClickListener(new ContactsAdapter.OnItemClickListener() {
@Override
public void onItemClick(View view, int position) {
handleItemClickByPosition(position);
}
});
...
private void handleItemClickByPosition(int position) {
switch (getAdapterPosition()) {
case 1:
ActivityUtil.startActivity(itemView.getContext(), BlablaActivity.class);
break;
//other cases
}
}
Hence you don't need to change the Adapter whenever there is new item in your Adapter.
Upvotes: 0
Reputation: 1126
First Save the Activity the items refers in your db and then add it to your typed list model if is the case like
yourlist.java
....
private String BLABLA;
private String BLABLA1;
private String ActivityName;
....
Then in your Adapter OnBindViewholder OnClick do Someting Like This
@Override
public void onClick(View v) {
activityString = singleItem.getActivityName();
Intent intent= new Intent(context, Class.forName(activityString));
context.startActivity(intent);
}
});
Upvotes: 2