i have a list and i showed that in recycler view
some of items have blue background and other items have gray background
i want to edit selected item background (
The selected item means the item that has been clicked )
this is my adapter class
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.UserViewHolder> {
private Context context;
private List<User> users = new ArrayList<>();
public UserAdapter(List<User> users, Context context) {
this.users = users;
this.context = context;
}
#NonNull
#Override
public UserViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new UserViewHolder(LayoutInflater.from(context).inflate(R.layout.item_user, parent, false));
}
#Override
public void onBindViewHolder(#NonNull UserViewHolder holder, int position) {
holder.binUser(users.get(position), position);
}
#Override
public int getItemCount() {
return users.size();
}
public class UserViewHolder extends RecyclerView.ViewHolder {
private TextView tvName;
private RelativeLayout rlItemUser;
public UserViewHolder(#NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tv_itemUser_name);
rlItemUser = itemView.findViewById(R.id.itemUser_rootView);
}
public void binUser(User user, int position){
tvName.setText(user.getName());
if (user.getMode().equals("passenger")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorGray));
tvName.setTextColor(context.getResources().getColor(R.color.colorPrimary));
} else if (user.getMode().equals("driver")){
rlItemUser.setBackgroundColor(context.getResources().getColor(R.color.colorPrimary));
tvName.setTextColor(context.getResources().getColor(R.color.colorGray));
}
}
}
in the bindUser method:
rlItemUser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rtlItemUser.setBackgroundColor(context.getResources().getColor(your color);
adapter.notifyItemChanged(position);
}
});
Related
I am working on an application where i have list of items in recyclerview on items i have a hear icon as wishlist the problem is when i click on the first item the last item automatically selected when i select the second item the second last got selected automatically. I dont know why this is happening?? please guide me
My RecyclerView Adapter
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.name.setText(datalist.get(position).getName());
holder.email.setText(datalist.get(position).getEmail());
holder.desc.setText(datalist.get(position).getDesc());
holder.book.setText(datalist.get(position).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(position).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(position);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int pos = holder.getBindingAdapterPosition();
if(compoundButton.isChecked())
{
Toast.makeText(context, "item added to wishlist" + pos , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "item removed to wishlist", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}
i click on the first heart icon
the last one is automatically clicked
Why this happening? Because when you scroll recyclerview remove hidden items automatically. For ex: 0 will be remove when scroll down and 1 item will be 0, 2 item will be 1 and 3->2,4->3 like this. There are 2 ways fix this error:
1) Simple way, but this method freeze your app when data is big:
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.setIsRecyclable(false);
}
2) If you want you use second method you must add unique_id to your arraylist each item:
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
private ArrayList<String> checkedItems=new ArrayList<>();
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
int pos=holder.getAdapterPosition();
holder.name.setText(datalist.get(pos).getName());
holder.email.setText(datalist.get(pos).getEmail());
holder.desc.setText(datalist.get(pos).getDesc());
holder.book.setText(datalist.get(pos).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(pos).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(pos);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
checkedItems.add(datalist.get(pos).getUniqueId());
} else {
checkedItems.remove(datalist.get(pos).getUniqueId());
}
}
});
// Check your selection here
if(checkedItems.contains(datalist.get(pos).getUniqueId())){
holder.wishlist.setChecked(true);
} else {
holder.wishlist.setChecked(false);
}
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}
When you call your Adapter in your Fragment or Activity, add this line before setAdapter()
recyclerView.setItemViewCacheSize(mData.size());
i have two adapters one for my card view and the other one for my drawer. The cards contains links to other options in the app and the drawer contains the same options. What i want is when user clicks on the card, the options in the drawer menu should get selected. Here is my code.
Drawer Adapter:
#SuppressWarnings({"rawtypes", "ConstantConditions"})
public class DrawerAdapter extends RecyclerView.Adapter<DrawerAdapter.ViewHolder> {
private List<DrawerItem> items;
private Map<Class<? extends DrawerItem>, Integer> viewTypes;
private SparseArray<DrawerItem> holderFactories;
private OnItemSelectedListener listener;
public DrawerAdapter(List<DrawerItem> items) {
this.items = items;
this.viewTypes = new HashMap<>();
this.holderFactories = new SparseArray<>();
processViewTypes();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
ViewHolder holder = holderFactories.get(viewType).createViewHolder(parent);
holder.adapter = this;
return holder;
}
#Override
#SuppressWarnings("unchecked")
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
items.get(position).bindViewHolder(holder);
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public int getItemViewType(int position) {
return viewTypes.get(items.get(position).getClass());
}
private void processViewTypes() {
int type = 0;
for (DrawerItem item : items) {
if (!viewTypes.containsKey(item.getClass())) {
viewTypes.put(item.getClass(), type);
holderFactories.put(type, item);
type++;
}
}
}
public void setSelected(int position) {
DrawerItem newChecked = items.get(position);
if (!newChecked.isSelectable()) {
return;
}
for (int i = 0; i < items.size(); i++) {
DrawerItem item = items.get(i);
if (item.isChecked()) {
item.setChecked(false);
notifyItemChanged(i);
break;
}
}
newChecked.setChecked(true);
notifyItemChanged(position);
if (listener != null) {
listener.onItemSelected(position);
}
}
public void setListener(OnItemSelectedListener listener) {
this.listener = listener;
}
static abstract class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private DrawerAdapter adapter;
public ViewHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
adapter.setSelected(getAdapterPosition());
}
}
public interface OnItemSelectedListener {
void onItemSelected(int position);
}
}
Card Adapter:
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {
;
private RecyclerView parentRecycler;
private List<Card> data;
public CardAdapter(List<Card> data) {
this.data = data;
}
#Override
public void onAttachedToRecyclerView(#NonNull RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
parentRecycler = recyclerView;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View v = inflater.inflate(R.layout.item_card, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Card card = data.get(position);
holder.getAdapterPosition();
Glide.with(holder.itemView.getContext())
.asGif()
.load(card.getCardIcon())
.into(holder.gifImageView);
holder.textView.setText(card.getCardName());
}
#Override
public int getItemCount() {
return data.size();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private GifImageView gifImageView;
private TextView textView;
public ViewHolder(View itemView) {
super(itemView);
gifImageView = itemView.findViewById(R.id.card_gif);
textView = itemView.findViewById(R.id.card_name);
itemView.findViewById(R.id.container).setOnClickListener(this);
}
public void showText() {
int parentHeight = ((View) gifImageView.getParent()).getHeight();
float scale = (parentHeight - textView.getHeight()) / (float) gifImageView.getHeight();
gifImageView.setPivotX(gifImageView.getWidth() * 0.5f);
gifImageView.setPivotY(0);
gifImageView.animate().scaleX(scale)
.withEndAction(new Runnable() {
#Override
public void run() {
textView.setVisibility(View.VISIBLE);
// gifImageView.setColorFilter(Color.BLACK);
}
})
.scaleY(scale).setDuration(200)
.start();
}
public void hideText() {
textView.setVisibility(View.INVISIBLE);
gifImageView.animate().scaleX(1f).scaleY(1f)
.setDuration(200)
.start();
}
#Override
public void onClick(View v) { parentRecycler.smoothScrollToPosition(getAdapterPosition());
}
}
}
}
P.S: I am new to programming any kind of help is appreciated.[As you can see in the image below that I have cards in the main view and the same options are in the drawer menu for example question papers. Now when the user clicks on question paper in the main view the question paper in drawer menu should get selected.[][1]][1]
thank you!
[1]: https://i.stack.imgur.com/FooVb.jpg
Here you can see I have plist in which I'm fetching the selected checkboxes when user clicks on select all button.
Here is that when I show the list of data. There is only the data of those checkboxes which are visible on screen and when I scroll down, remaining checkboxes get selected and when I scroll some more time it another repeated values of selected checkboxes
Adapter.java
public class AttendanceRegisterAdapter extends RecyclerView.Adapter<AttendanceRegisterAdapter.AttendanceViewHolder> {
Context context;
private ArrayList<Student> student;
private boolean isSelectedAll;
private ArrayList<String> plist = new ArrayList<>();
public AttendanceRegisterAdapter(Context context, ArrayList<Student> student) {
this.context = context;
this.student = student;
}
#NonNull
#Override
public AttendanceViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.template_card_student, parent, false);
return new AttendanceViewHolder(view);
}
public void selectAll() {
isSelectedAll = true;
notifyDataSetChanged();
}
public void unSelectAll() {
isSelectedAll = false;
notifyDataSetChanged();
}
#Override
public void onBindViewHolder(#NonNull AttendanceViewHolder holder, int position) {
final Student selectedList = student.get(position);
holder.cbAttendance.setSelected(selectedList.getSelected());
holder.cbAttendance.setTag(position);
if (isSelectedAll) {
selectedList.setSelected(true);
plist.add(student.get(position).getStudentID());
} else {
selectedList.setSelected(false);
plist.remove(student.get(position).getStudentID());
}
holder.cbAttendance.setChecked(selectedList.getSelected());
}
#Override
public int getItemCount() {
return student.size();
}
class AttendanceViewHolder extends RecyclerView.ViewHolder {
CardView cvStudentCard;
ImageView imgStudentPicture;
TextView txtStudentName;
CheckBox cbAttendance;
public AttendanceViewHolder(#NonNull View itemView) {
super(itemView);
cvStudentCard = itemView.findViewById(R.id.card_student_view);
imgStudentPicture = itemView.findViewById(R.id.img_student_picture);
txtStudentName = itemView.findViewById(R.id.tv_card_title);
cbAttendance = itemView.findViewById(R.id.cb_attendance);
}
}
}
You are adding StudentId in BindViewHolder without checking plist
maybe duplicate values are added each time BindViewHolder is called.
public class AttendanceRegisterAdapter extends RecyclerView.Adapter<AttendanceRegisterAdapter.AttendanceViewHolder> {
Context context;
private ArrayList<Student> student;
private boolean isSelectedAll;
private ArrayList<String> plist = new ArrayList<>();
public AttendanceRegisterAdapter(Context context, ArrayList<Student> student) {
this.context = context;
this.student = student;
}
#NonNull
#Override
public AttendanceViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.template_card_student, parent, false);
return new AttendanceViewHolder(view);
}
public void selectAll() {
isSelectedAll = true;
notifyDataSetChanged();
}
public void unSelectAll() {
isSelectedAll = false;
notifyDataSetChanged();
}
public Boolean checkElementExist(String element) {
return plist.contains(element);
}
public void selectLeftOver(int nextPosition) {
for (int i = nextPosition; nextPosition > getItemCount(); i++) {
if (!checkElementExist(student.get(i).getStudentID())) {
plist.add(student.get(i).getStudentID());
}
}
}
#Override
public void onBindViewHolder(#NonNull AttendanceViewHolder holder, int position) {
final Student selectedList = student.get(position);
holder.cbAttendance.setSelected(selectedList.getSelected());
holder.cbAttendance.setTag(position);
if (isSelectedAll) {
selectedList.setSelected(true);
if (!checkElementExist(student.get(position).getStudentID())) {
plist.add(student.get(position).getStudentID());
selectLeftOver(position + 1);
}
} else {
selectedList.setSelected(false);
if (!checkElementExist(student.get(position).getStudentID())) {
plist.remove(student.get(position).getStudentID());
}
}
holder.cbAttendance.setChecked(selectedList.getSelected());
}
#Override
public int getItemCount() {
return student.size();
}
class AttendanceViewHolder extends RecyclerView.ViewHolder {
CardView cvStudentCard;
ImageView imgStudentPicture;
TextView txtStudentName;
CheckBox cbAttendance;
public AttendanceViewHolder(#NonNull View itemView) {
super(itemView);
cvStudentCard = itemView.findViewById(R.id.card_student_view);
imgStudentPicture = itemView.findViewById(R.id.img_student_picture);
txtStudentName = itemView.findViewById(R.id.tv_card_title);
cbAttendance = itemView.findViewById(R.id.cb_attendance);
}
}
}
In MainActivity, I have created an Array of Array of Chip and inflated to the Recyclerview. Inside the RecyclerAdapter, I had to remove the parent of chips to be able to put each Array in a ChipGroup.
Now I need to get all ChipGroups (and their chips) in MainActivity. I have tried ChipGroup cg = (ChipGroup) findElementByID(R.id.chip_row_chipgroup) but only retrieves the first ChipGroup (Apparently because I removed the parent of the rest)
RecyclerAdapter.java
public class ChipSelectAdapter extends RecyclerView.Adapter<ChipSelectAdapter.ViewHolder> {
private ArrayList<ArrayList<Chip>> items;
private Context context;
public ChipSelectAdapter(Context context, ArrayList<ArrayList<Chip>> chips) {
this.context = context;
this.items = chips;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.chip_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
viewHolder.setIsRecyclable(false);
for (Chip chip : items.get(position))
{
if(chip.getParent() != null)
{
((ViewGroup)chip.getParent()).removeView(chip);
}
viewHolder.chipGroup.addView(chip);
}
// listener
viewHolder.itemView.setOnClickListener (new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do something!
}
});
}
#Override
public int getItemCount() {
return items.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ChipGroup chipGroup;
public ViewHolder(View view) {
super(view);
chipGroup = (ChipGroup) view.findViewById(R.id.chip_row_chipgroup);
}
}
}
I have a recycler view that displays a list of items.
Within each item, there is a title and another RecyclerView that display a list of items.
I want to access the click events of the items of the child RecyclerView.
Screenshot of the layout:
The parent RecyclerView:
public class DetailsGroupAdapter extends RecyclerView.Adapter<DetailsGroupAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
RecyclerView mRecyclerView;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onGroupItemLongClick(View itemView, int groupPosition, int itemPosition);
void onGroupItemClick(View itemView, int groupPosition, int itemPosition);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public CardView cvContainer;
public RecyclerView rvItems;
public ViewHolder(final View itemView)
{
super(itemView);
tvTitle = itemView.findViewById(R.id.group_title);
cvContainer = itemView.findViewById(R.id.container);
rvItems = itemView.findViewById(R.id.rv_group_items);
//click listener setup
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Triggers click upwards to the adapter on click
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
}
public void clearAnimation()
{
cvContainer.clearAnimation();
}
}
private List<DetailsGroup> itemList;
public DetailsGroupAdapter(List<DetailsGroup> itemList)
{
this.itemList = itemList;
}
#Override
public DetailsGroupAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details_group, parent, false);
mRecyclerView = (RecyclerView) parent;
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(final DetailsGroupAdapter.ViewHolder viewHolder, int groupPosition){
final DetailsGroup detailsGroup = itemList.get(groupPosition);
if(detailsGroup.Title != null){
viewHolder.tvTitle.setText(detailsGroup.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
final DetailsGroupItemsAdapter detailsGroupAdapter = new DetailsGroupItemsAdapter(detailsGroup.itemsList, groupPosition);
detailsGroupAdapter.setOnItemClickListener(new DetailsGroupItemsAdapter.OnItemClickListener() {
#Override
public void onItemClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
}
}
#Override
public void onLongClick(View itemView, int position) {
if (listener != null){
listener.onGroupItemLongClick(itemView, (int) itemView.getTag(), position);
}
}
});
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(context) {};
viewHolder.rvItems.setLayoutManager(linearLayoutManager);
viewHolder.rvItems.setAdapter(detailsGroupAdapter);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).cvContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<DetailsGroup> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The child RecyclerView:
public class DetailsGroupItemsAdapter extends RecyclerView.Adapter<DetailsGroupItemsAdapter.ViewHolder>{
private static OnItemClickListener listener;
private Context context;
private int lastPosition = -1;
private int groupPosition;
public interface OnItemClickListener {
void onItemClick(View itemView, int position);
void onLongClick(View itemView,int position);
}
public void setOnItemClickListener(OnItemClickListener listener) {
DetailsGroupItemsAdapter.listener = listener;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvTitle;
public TextView tvSubTitle;
public ImageView ivThumbnail;
public LinearLayout llContainer;
public ViewHolder(final View itemView)
{
super(itemView);
ivThumbnail = itemView.findViewById(R.id.thumbnail);
tvTitle = itemView.findViewById(R.id.title);
tvSubTitle = itemView.findViewById(R.id.subtitle);
llContainer = itemView.findViewById(R.id.container);
itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (listener != null)
listener.onItemClick(itemView, getLayoutPosition());
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (listener != null)
listener.onLongClick(itemView, getLayoutPosition());
return false;
}
});
}
public void clearAnimation()
{
llContainer.clearAnimation();
}
}
private List<ItemDetail> itemList;
public DetailsGroupItemsAdapter(List<ItemDetail> itemList, int groupPosition)
{
this.itemList = itemList;
this.groupPosition = groupPosition;
}
#Override
public DetailsGroupItemsAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View layoutView = inflater.inflate(R.layout.item_details, parent, false);
return new ViewHolder(layoutView);
}
#Override
public void onBindViewHolder(DetailsGroupItemsAdapter.ViewHolder viewHolder, int position){
viewHolder.itemView.setTag(groupPosition);
ItemDetail itemDetail = itemList.get(position);
if(itemDetail.Title != null){
viewHolder.tvTitle.setText(itemDetail.Title);
} else {
viewHolder.tvTitle.setVisibility(View.GONE);
}
if(itemDetail.Sub_Title != null){
viewHolder.tvSubTitle.setText(itemDetail.Sub_Title);
} else {
viewHolder.tvSubTitle.setVisibility(View.GONE);
}
if(itemDetail.Thumbnail_Enabled){
PicManipulationUtility.SetGenericPictureFromThumbnailType(viewHolder.ivThumbnail, itemDetail.Thumbnail_Type, itemDetail.Thumbnail);
} else {
viewHolder.ivThumbnail.setVisibility(View.GONE);
}
setAnimation(viewHolder.llContainer, position);
}
private void setAnimation(View viewToAnimate, int position)
{
if (position > lastPosition) {
AlphaAnimation anim = new AlphaAnimation(0.0f, 1.0f);
anim.setDuration(1000);
viewToAnimate.startAnimation(anim);
lastPosition = position;
}
}
#Override
public void onViewDetachedFromWindow(final ViewHolder holder)
{
((ViewHolder)holder).llContainer.clearAnimation();
}
#Override
public long getItemId(int position) {
return itemList.get(position).hashCode();
}
#Override
public int getItemCount()
{
return itemList.size();
}
public void clear() {
itemList.clear();
notifyDataSetChanged();
}
public void addAll(List<ItemDetail> list){
itemList.addAll(list);
notifyDataSetChanged();
}
}
The classes used:
ItemDetail and DetailsGroup are POJOs to convert JSON into objects.
What I managed to do so far to temporarily fix the problem is:
In onBindViewHolder of parent RecyclerView, I grabbed the group position.
Then I passed the group position of the parent down to the child
adapter initializer in (DetailsGroupItemsAdapter)
Finally, in the child onBindViewHolder I set the tag to be the parent
group position(viewHolder.itemView.setTag(groupPosition);)
So in the click event of the child, I can say:
listener.onGroupItemClick(itemView, (int) itemView.getTag(), position);
Thus having both the group position and the child position in the bubbled event in my Activity or Fragment.
But I know for sure that the passed group position can change for any reason such as updating group items or removing items.
I want to know if there is a more robust solution to implement the click events of nested items in this case.
I used this https://gist.github.com/riyazMuhammad/1c7b1f9fa3065aa5a46f, especially
CustomItemClickListener.java :
public interface CustomItemClickListener {
public void onItemClick(View v, int position);
}
(Parent) RecyclerView modifications :
public class ItemsListAdapter extends RecyclerView.Adapter<ItemsListAdapter.ViewHolder> {
ArrayList<ItemListSingleItem> data;
Context mContext;
CustomItemClickListener listener;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View mView = LayoutInflater.from(parent.getContext()).inflate(R.layout.items_list_single_item, parent, false);
final ViewHolder mViewHolder = new ViewHolder(mView);
mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listener.onItemClick(v, mViewHolder.getPosition());
}
});
return mViewHolder;
}
//[... the other "classical" parts of your code...]
}
Alone, it allowed me to have separate click events on child and parent
With some modifications, it led me to something similar to your "fix", I think, but maybe it'll give you some clues : I am giving the parent position and the parent listener to the child when constructing it, and then a click on the child produces the same behavior as a click on the parent
Child RecyclerView constructor :
public AppsAdapter(ArrayList<PackageInformation.InfoObject> dataSet, CustomOnItemClickListener customItemClickListener, int parentPos) {
appsDataSet = dataSet;
onItemClickListener = customItemClickListener;
parentPosition = parentPos;
}
Child RecyclerView onCreateViewHolder :
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view.
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_app, viewGroup, false);
// Create the ViewHolder to return
final AppsAdapter.ViewHolder mViewHolder = new AppsAdapter.ViewHolder(v);
// Add the Listener
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) { onItemClickListener.onItemClick(v, parentPosition); }
});
return mViewHolder;