I have a RecyclerView filled with elements of the "Event" class. The class has parameters such as Date and Importance.
Now all Events in RecyclerView are displayed just like that.
I want to show Events by Date separately and also want to show Events by importance separately. I'll attach a picture to show what I mean.
I read that to do separation, for example, by dates, you need to make a separate adapter and viewholder. Question - if I want to split the same data array by importance, do I need to create another adapter?
And let's say I want to choose a grouping method. How can I do this and where?
My First RecyclerViewAdapter of Event
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private static final String TAG = "myLogs";
private List<Event> mEventList;
final SparseBooleanArray selectedItems = new SparseBooleanArray();
private int currentSelectedPos;
public List<Event> getEvents(){
return mEventList;
}
private EventAdapterListener itemClickListener;
public interface EventAdapterListener {
void onItemClick(int position);
void onItemLongClick(int position);
}
public void setListener(EventAdapterListener listener){
itemClickListener = listener;
}
private OnItemCheckedListener OnItemChecked;
public interface OnItemCheckedListener {
void onItemChecked(int position, boolean isImportant);
}
public void setOnItemCheckedListener (OnItemCheckedListener listener){
OnItemChecked = listener;
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public TextView TVtitle;
public TextView TVcomment;
public CheckBox CBimportance;
public TextView TVdate;
//public EventViewHolder(#NonNull View itemView, final EventAdapterListener listener) {
public EventViewHolder(#NonNull View itemView) {
super(itemView);
TVtitle = itemView.findViewById(R.id.tvTitle);
TVcomment = itemView.findViewById(R.id.tvComment);
CBimportance = itemView.findViewById(R.id.cbIconImportant);
TVdate = itemView.findViewById(R.id.tvDate);
}
}
public void removeItem(int position) {
mEventList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mEventList.size());
}
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
public EventAdapter(ArrayList<Event> listEvent){
mEventList = listEvent;
}
#NonNull
#Override
public EventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_cardview, parent, false);
//LayoutInflater inflater = LayoutInflater.from(parent.getContext());
//if (viewType == Constants.VIEWTYPE_GROUP){
//ViewGroup group = (ViewGroup) inflater.inflate(R.layout.group_layout, parent, false);
//GroupViewHolder
//}
return new EventViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, final int position) {
final Event item = mEventList.get(position);
holder.TVtitle.setText(item.getName());
holder.TVcomment.setText(item.getComment());
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
holder.TVdate.setText(simpleDateFormat.format(item.getDate()));
holder.CBimportance.setOnCheckedChangeListener(null);
holder.CBimportance.setChecked(item.getImportant());
holder.CBimportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.IsImportant = b;
OnItemChecked.onItemChecked(position, b);
}
});
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (selectedItems.size() > 0 && itemClickListener != null){
itemClickListener.onItemClick(position);
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
if (itemClickListener != null){
itemClickListener.onItemLongClick(position);
}
return true;
}
});
if (currentSelectedPos == position) currentSelectedPos = -1;
}
#Override
public int getItemCount() {
return mEventList.size();
}
void deleteEvents(){
List<Event> events = new ArrayList<>();
for (Event event : mEventList){
if (event.getSelected())
events.add(event);
}
mEventList.removeAll(events);
notifyDataSetChanged();
currentSelectedPos = -1;
}
void toggleSelection(int position) {
currentSelectedPos = position;
if (selectedItems.get(position)) {
selectedItems.delete(position);
mEventList.get(position).setSelected(false);
} else {
selectedItems.put(position, true);
mEventList.get(position).setSelected(true);
}
notifyItemChanged(position);
}}
Related
I am using a RecyclerView and an adapter to display the data of an array of Classes objects. I have a MainHolder and two subHolders - ItemHolder and HeaderHolder. ItemHolder has Checkbox. In RecyclerView, I use a CheckBox for one of the object's parameters. How can I save it? For the rest I use SharedPreferences, but here I don't know how to apply it in my Activity.
Here's my MainHolder:
public abstract class MainHolder extends RecyclerView.ViewHolder {
abstract void setData(MainItem item);
public MainHolder(#NonNull View itemView) {
super(itemView);
}
}
And ItemHolder:
public class ItemHolder extends MainHolder{
private TextView tvTitle, tvComment, tvDate;
private CheckBox cbImportance;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
#Override
void setData(MainItem item) {
final Event event = item.getEventItem();
tvTitle.setText(event.getName());
tvComment.setText(event.getComment());
tvDate.setText(simpleDateFormat.format(event.getDate()));
cbImportance.setOnCheckedChangeListener(null);
cbImportance.setChecked(event.getImportant());
cbImportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
event.IsImportant = b;
}
});
}
public ItemHolder(#NonNull View itemView) {
super(itemView);
tvTitle = itemView.findViewById(R.id.tvTitle);
tvComment = itemView.findViewById(R.id.tvComment);
tvDate = itemView.findViewById(R.id.tvDate);
cbImportance = itemView.findViewById(R.id.cbIconImportant);
}
}
Here's my Adapter
public class MainAdapter extends RecyclerView.Adapter<MainHolder> {
private Context context;
private ArrayList<MainItem> data;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd MMMM", myDateFormatSymbols);
private OnItemCheckedListener mOnItemChecked;
public interface OnItemCheckedListener{
void onItemChecked(int position, boolean isImportant);
}
public void setOnItemCheckedListener(OnItemCheckedListener listener){
mOnItemChecked = listener;
}
private static DateFormatSymbols myDateFormatSymbols = new DateFormatSymbols(){
#Override
public String[] getMonths() {
return new String[]{"января", "февраля", "марта", "апреля", "мая", "июня",
"июля", "августа", "сентября", "октября", "ноября", "декабря"};
}
};
public MainAdapter(Context context, ArrayList<MainItem> data) {
this.context = context;
this.data = data;
}
#NonNull
#Override
public MainHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType){
case (Constants.ITEM_HEADER_TEXT_VIEWTYPE):
view = LayoutInflater.from(context).inflate(R.layout.group_layout, parent, false);
return new HeaderHolder(view);
case (Constants.ITEM_EVENT_TEXT_VIEWTYPE):
view = LayoutInflater.from(context).inflate(R.layout.list_item_cardview, parent, false);
return new ItemHolder(view);
default: throw new IllegalArgumentException();
}
}
#Override
public void onBindViewHolder(#NonNull final MainHolder holder, final int position) {
holder.setData(data.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.getItemViewType() == Constants.ITEM_HEADER_TEXT_VIEWTYPE)
Toast.makeText(context, "Нажал на заголовок" + position, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Нажал на айтем" + position, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemViewType(int position) {
return data.get(position).getViewType();
}
Ok, I made the checkbox public in ItemHolder.
And in OnBindHolder I made OnCheckedChanged for Checkbox
#Override
public void onBindViewHolder(#NonNull final MainHolder holder, final int position) {
holder.setData(data.get(position));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.getItemViewType() == Constants.ITEM_HEADER_TEXT_VIEWTYPE)
Toast.makeText(context, "Нажал на заголовок" + position, Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "Нажал на айтем" + position, Toast.LENGTH_SHORT).show();
}
});
if (holder.getItemViewType() == Constants.ITEM_EVENT_TEXT_VIEWTYPE){
((ItemHolder) holder).cbImportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
data.get(position).getEventItem().IsImportant = b;
if (b){
Toast.makeText(context, "IMPORTANT", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(context, "NON IMPORTANT", Toast.LENGTH_SHORT).show();
}
notifyDataSetChanged();
mOnItemChecked.onItemChecked(position, b);
}
});
}
}
In the fragment I write state of the checkbox.
adapterEvent.setOnItemCheckedListener(new MainAdapter.OnItemCheckedListener() {
#Override
public void onItemChecked(int position, boolean isImportant) {
write(getContext(), events, PROCESSED_EVENTS);
ShowEvents(ShowMode);
}
});
I am using a RecyclerView and an adapter to display the data of an array of Event objects. In RecyclerView, I use a CheckBox for one of the object's parameters. How can I save it?
For the rest I use SharedPreferences, but here I don't know how to apply it in my Activity.
Here's my class Event:
public class Event implements Serializable {
public String Name;
public Long Date;
public String Comment;
public String Type;
public String Notify;
public Boolean IsComplete;
public Boolean IsImportant;
Event()
{
Name = "Событие";
Date = MaterialDatePicker.todayInUtcMilliseconds();
Comment = "Comment";
Type = "Material";
Notify = "Не напоминать";
IsComplete = false;
IsImportant = false;
}
Event(String name, Long date, String comment, String type, String notify, Boolean iscomplete, Boolean isimportant)
{
Name = name;
Date = date;
Comment = comment;
Type = type;
Notify = notify;
IsComplete = iscomplete;
IsImportant = isimportant;
}
public String getName() {
return Name;
}
public Long getDate() {
return Date;
}
public String getComment() {
return Comment;
}
public String getType() {
return Type;
}
public String getNotify() {
return Notify;
}
public Boolean getComplete() {
return IsComplete;
}
public Boolean getImportant() {
return IsImportant;
}
}
And my Recycler View and Adapter:
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private static final String TAG = "myLogs";
private ArrayList<Event> mEventList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public TextView TVtitle;
public TextView TVcomment;
public CheckBox CBimportance;
public EventViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
TVtitle = itemView.findViewById(R.id.tv1);
TVcomment = itemView.findViewById(R.id.tv2);
CBimportance = itemView.findViewById(R.id.iconImportant);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
public EventAdapter(ArrayList<Event> listEvent){
mEventList = listEvent;}
#NonNull
#Override
public EventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_cardview, parent, false);
EventViewHolder evh = new EventViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, final int position) {
final Event item = mEventList.get(position);
holder.TVtitle.setText(item.getName());
holder.TVcomment.setText(item.getComment());
holder.CBimportance.setOnCheckedChangeListener(null);
holder.CBimportance.setChecked(item.getImportant());
holder.CBimportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.IsImportant = b;
if (b){
Log.d(TAG, String.valueOf(position) + " IMPORTANT");
}
else{
Log.d(TAG, String.valueOf(position) + " NON IMPORTANT");
}
}
});
}
#Override
public int getItemCount() {
return mEventList.size();
}
}
For example, for ItemClick and changes saving in my Activity I use onItemClick:
adapterEvent.setOnItemClickListener(new EventAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
eventsProcess.remove(position);
adapterEvent.notifyItemRemoved(position);
write(getContext(), eventsProcess, PROCESSED_EVENTS);
}
});
public static void write(Context context, ArrayList<Event> events, String Key)
{
Gson gson = new Gson();
String jsonString = gson.toJson(events);
SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = pref.edit();
editor.putString(Key, jsonString);
editor.apply();
}
You should be able to do this exactly how you handle the 'OnItemClick'. I made some changes in your adapter to add a new interface OnItemCheckedListener and then handle the checkbox checkedChanged events using this listener. (Instead of just logging it like you did).
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventViewHolder> {
private static final String TAG = "myLogs";
private ArrayList<Event> mEventList;
private OnItemClickListener mListener;
public interface OnItemClickListener {
void onItemClick(int position);
}
public void setOnItemClickListener(OnItemClickListener listener){
mListener = listener;
}
private OnItemCheckedListener mOnItemChecked;
public interface OnItemCheckedListener {
void onItemChecked (int position, boolean isImportant);
}
public void setOnItemCheckedListener (OnItemCheckedListener listener) {
mOnItemChecked = listener;
}
public static class EventViewHolder extends RecyclerView.ViewHolder{
public TextView TVtitle;
public TextView TVcomment;
public CheckBox CBimportance;
public EventViewHolder(#NonNull View itemView, final OnItemClickListener listener) {
super(itemView);
TVtitle = itemView.findViewById(R.id.tv1);
TVcomment = itemView.findViewById(R.id.tv2);
CBimportance = itemView.findViewById(R.id.iconImportant);
itemView.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
if (listener != null){
int position = getAdapterPosition();
if (position != RecyclerView.NO_POSITION){
listener.onItemClick(position);
}
}
}
});
}
}
public EventAdapter(ArrayList<Event> listEvent){
mEventList = listEvent;
}
#NonNull
#Override
public EventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_cardview, parent, false);
EventViewHolder evh = new EventViewHolder(v, mListener);
return evh;
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, final int position) {
final Event item = mEventList.get(position);
holder.TVtitle.setText(item.getName());
holder.TVcomment.setText(item.getComment());
holder.CBimportance.setOnCheckedChangeListener(null);
holder.CBimportance.setChecked(item.getImportant());
holder.CBimportance.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
item.IsImportant = b;
if (b) {
Log.d(TAG, String.valueOf(position) + " IMPORTANT");
}
else{
Log.d(TAG, String.valueOf(position) + " NON IMPORTANT");
}
mOnItemChecked.onItemChecked(position, b)
}
});
}
#Override
public int getItemCount() {
return mEventList.size();
}
}
Now, From your activity just set the OnItemCheckedListener of the EventAdapter.
adapterEvent.setOnItemCheckedListener(new EventAdapter.OnItemCheckedListener {
#Override
public void onItemChecked (int position, boolean isImportant) {
// TODO:
// whatever you want to do with the isImportant data
}
});
I would like to change the color when I click the Button in RecyclerView.
I want to change the text color of the 4 button when I click the button corresponding to position 4 of position 1, 2, 3, 4.
public class SingleAdapter extends RecyclerView.Adapter<SingleAdapter.ViewHolder> {
public interface OnItemClickListener {
void onItemClick(int position);
void onLongItemClick(int position);
}
Context context;
List<SingleItem> items;
public static OnItemClickListener onItemClickListener;
public SingleAdapter(Context context, List<SingleItem> items) {
this.context = context;
this.items = items;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener)
{
this.onItemClickListener = onItemClickListener;
}
#Override
public int getItemCount() {
return items.size();
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.single_item, parent, false);
final ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
SingleItem item = items.get(position);
viewHolder.btnItemButton.setText(item.getmSubText());
}
static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
Button btnItemButton;
public ViewHolder(#NonNull final View itemView) {
super(itemView);
btnItemButton = itemView.findViewById(R.id.itemButton);
btnItemButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(onItemClickListener != null)
{
onItemClickListener.onItemClick(getAdapterPosition());
}
}
#Override
public boolean onLongClick(View v) {
return false;
}
}
}
public class SingleItem {
String mSubText;
public SingleItem(String mSubText)
{
this.mSubText = mSubText;
}
public String getmSubText() {
return mSubText;
}
public void setmSubText(String mSubText)
{
this.mSubText = mSubText;
}
}
static String mAddListDepthUnits[] = { "m", "ft", "fm", "HR", "pb" };
private void setDepthRecycler()
{
singleItems = new ArrayList<>();
for( int i = 0; i < mAddListDepthUnits.length; i++)
{
singleItems.add(new SingleItem(mAddListDepthUnits[i]));
}
mSingleAdapter = new fec.fishfinderapp.menu.SingleAdapter(mSubMenu_Units.getContext(), singleItems);
midDepthRecycler.setAdapter(mSingleAdapter);
mSingleAdapter.setOnItemClickListener(new SingleAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position) {
switch(position)
{
case 0 :
case 1 :
case 2 :
case 3 :
case 4 :
case 5 :
break;
}
}
#Override
public void onLongItemClick(int position) {
}
});
}
The current code is in this state.
How can I change the text color of a specific button here?
I can hardly find the answer.
Please help me
As my understanding you need to change the text color based on button click?
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int position) {
SingleItem item = items.get(position);
viewHolder.btnItemButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(position == 4) {
viewHolder.btnItemButton.setTextColor(Color.RED);
}else{
viewHolder.btnItemButton.setTextColor(Color.GREEN);
}
}
});
viewHolder.btnItemButton.setText(item.getmSubText());
}
My Title is kind of hard to understand but basically when I add items into my database is should display it in a RecyclerView. Now in my RecyclerView I have two layouts but the problem is the first item of my database goes behind my first item in my other layout. So if I have 3 items in my database, it shows only 2 items from the database and the first item hides behind my first item in the RecyclerView which is a different layout that does not use the database at all.
This is my code:
FirebaseRecyclerOptions<Event> firebaseRecyclerOptions = new FirebaseRecyclerOptions.Builder<Event>()
.setQuery(query1, Event.class).build();
AccAdapter = new FirebaseRecyclerAdapter<Event, RecyclerView.ViewHolder>(firebaseRecyclerOptions){
final static int TYPE_HEADER = 0;
final static int TYPE_ITEM = 1;
#Override
public int getItemViewType(int position) {
if (position == 0) return TYPE_HEADER;
return TYPE_ITEM;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER){
View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_add_items,
parent, false);
return new ProdudctHolder3(view);
} else {
View view = LayoutInflater.from(getActivity()).inflate(R.layout.recycler_view_row_acc,
parent, false);
return new ProductHolder2(view);
}
}
#Override
protected void onBindViewHolder(final RecyclerView.ViewHolder holder, int position, final Event model) {
if (holder instanceof ProdudctHolder3){
((ProdudctHolder3) holder).addBackground.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getActivity(), AccAddItems.class ));
}
});
} else{
final ProductHolder2 productHolder2 = (ProductHolder2) holder;
productHolder2.mName.setText(model.getName());
productHolder2.view.setBackgroundResource(getBackgroundDrawable(Integer.valueOf(model.getProductAmount())));
productHolder2.mbackground.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.popup_edit_product);
SeekBar amountSeekBar = dialog.findViewById(R.id.amountSeekBar);
amountSeekBar.setMax(100);
amountSeekBar.setProgress(Integer.valueOf(model.getProductAmount()));
amountSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
progress = i;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
getRef(holder.getAdapterPosition()).child("productAmount").setValue(String.valueOf(progress));
dialog.dismiss();
}
});
dialog.show();
}
});
productHolder2.mbackground.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
final PopupMenu popupMenu = new PopupMenu(getActivity(), productHolder2.mbackground);
popupMenu.inflate(R.menu.menu_acc);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
switch (menuItem.getItemId()){
case R.id.deleteProduct:
getRef(productHolder2.getAdapterPosition()).removeValue();
popupMenu.dismiss();
return true;
default:
return false;
}
}
});
popupMenu.show();
return true;
}
});
}
}
};
mAccRecyclerViewRef.setAdapter(AccAdapter);
My two Product Holders
private class ProdudctHolder3 extends RecyclerView.ViewHolder{
private RelativeLayout addBackground;
public ProdudctHolder3(View itemView) {
super(itemView);
addBackground = itemView.findViewById(R.id.mBackground2);
}
}
private class ProductHolder2 extends RecyclerView.ViewHolder{
private TextView mName;
private RelativeLayout mbackground;
private View view;
public ProductHolder2(View itemView) {
super(itemView);
mName = itemView.findViewById(R.id.ItemName);
mbackground = itemView.findViewById(R.id.mBackground1);
view = itemView.findViewById(R.id.amountIndicator);
}
}
The ideal solution would have been to set two adapters on a single RecyclerView but unfortunatelly this is not possible.
However, you can make a single custom Adapter that handles two types of items. I will explain this by getting an example.
Let's assume you need to display objects of two types, humans and aliens. Your objects require completely different layouts and completely different ViewHolders. Please see the below code for the ViewHolders:
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static class HumanViewHolder extends RecyclerView.ViewHolder {
public HumanViewHolder(View itemView) {
super(itemView);
//Prepare your ViewHolder
}
public void bind(Human human) {
//Display your human object
}
}
private static class AlienViewHolder extends RecyclerView.ViewHolder {
public AlienViewHolder(View itemView) {
super(itemView);
//Prepare your ViewHolder
}
public void bind(Alien alien) {
//Display your alien object
}
}
}
First you need to add two different constants to your adapter representing both type of views:
private static final int ITEM_TYPE_HUMAN;
private static final int ITEM_TYPE_ALIEN;
To keep things simple, let's also assume you store your objects in a list:
private List<Object> items = new ArrayList<>();
public MyAdapter(List<Object> items) {
this.items.addAll(items);
//Other stuff if needed
}
Now, the first you need to do, is to implement getItemViewType() method:
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Human) {
return ITEM_TYPE_HUMAN;
} else {
return ITEM_TYPE_ALIEN;
}
}
Second, you need to use the item type inside the onCreateViewHolder() method like this:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
if (viewType == ITEM_TYPE_HUMAN) {
View view = layoutInflater.inflate(R.layout.item_human, parent, false);
return new HumanViewHolder(view);
} else {
View view = layoutInflater.inflate(R.layout.item_alien, parent, false);
return new AlienViewHolder(view);
}
}
In the end, you just need to bind the proper view holder like this:
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
Object item = items.get(position);
if (viewHolder instanceof HumanViewHolder) {
((HumanViewHolder) viewHolder).bind((Human) item);
} else {
((AlienViewHolder) viewHolder).bind((Alien) item);
}
}
Why use the Firebase Recycler Adapter when you could easily make a custom one? If I understood well you want an item to be fixed at position 0 (header) while others will be added below the first one, right? If so, here is a solution I like to use:
public interface ViewType {
public int getViewType();
}
public interface ViewTypeDelegateAdapter {
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent);
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item);
}
public class ViewTypes {
public static int HEADER = 0
public static int ITEM = 1
}
public class ProductDelegateAdapter implements ViewTypeDelegateAdapter {
private int resID;
private Context context;
public ProductDelegateAdapter(int resID, Context context) {
this.resID = resID;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new ProductHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
(holder as ProductHolder).bind("test");
}
class ProductHolder extends RecyclerView.ViewHolder {
public ProductHolder(View view) {
super(view);
}
public void bind(String test) {
}
}
}
public class HeaderDelegateAdapter implements ViewTypeDelegateAdapter {
private int resID;
private Context context;
public ProductDelegateAdapter(int resID, Context context) {
this.resID = resID;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent) {
return new HeaderHolder(LayoutInflater.from(parent.context).inflate(resID, parent, false));
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, ViewType item) {
(holder as HeaderHolder).bind("test");
}
class HeaderHolder extends RecyclerView.ViewHolder {
public HeaderHolder(View view) {
super(view);
}
public void bind(String test) {
}
}
}
public class AccAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private Context context;
private List<ViewType> items;
private SparseArrayCompat<ViewTypeDelegateAdapter> delegateAdapters;
private ViewType headerItem;
public AccAdapter(Context context) {
this.context = context;
this.items = new ArrayList();
this.delegateAdapters = new SparseArrayCompat();
this.headerItem = new ViewType() {
#Override
public int getViewType() {
return ViewTypes.HEADER;
}
};
this.items.add(this.headerItem);
this.delegateAdapters.put(ViewTypes.HEADER, HeaderDelegateAdapter(R.id.test, this.context));
this.delegateAdapters.put(ViewTypes.ITEM, ProductDelegateAdapter(R.id.test, this.context));
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, Int viewType) {
return delegateAdapters.get(viewType).onCreateViewHolder(parent);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, Int position) {
delegateAdapters.get(getItemViewType(position)).onBindViewHolder(holder, items[position])
}
#Override
public Int getItemViewType(Int position) {
return items.get(position).getViewType();
}
#Override
public Int getItemCount() {
return items.getSize();
}
public void add(ViewType viewType) {
val initPosition = this.items.size - 1
this.items.add(item)
notifyItemRangeChanged(initPosition, this.items.size + 1)
}
}
public class Event implements ViewType {
private String id;
#Override
public int getViewType() {
return ViewTypes.ITEM;
}
}
Excuse me for some syntax errors, I've translated to Java from Kotlin to help you. Hope it helps!
How can handle with this situation -> I have a list of itens in a recyclerView and I want to choose one of those option: green, yellow or red face to get the value of object from list item I chose
So I thought something like bellow, but when I select one of those faces anything happens. I think that button click listener doesn't work. Please someone can drive me to a better suggestion that works, give me an example or could me tell what am I doing wrong?
My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private SparseBooleanArray selectedItems;
public LikeListAdapter(List<Goals> goalsList) {
this.goalsList = goalsList;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
return new LikeItemViewHolder(view);
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("fretgr", "get Green Point = " + goals.getGreenPoint());
setToggleSelection(1);
}
});
holder.sosoButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("rtret", "get Yellow Point = " + goals.getYellowPoint());
setToggleSelection(2);
}
});
holder.angryButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("ewwr", "get Red Point = " + goals.getRedPoint());
setToggleSelection(3);
}
});
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
// method to access in activity after updating selection
public List<Goals> getGoalsList() {
return goalsList;
}
public void setToggleSelection(int pointType){
selectedItems = new SparseBooleanArray();
if (selectedItems.get(pointType, false)) {
selectedItems.delete(pointType);
} else {
selectedItems.put(pointType, true);
}
notifyItemChanged(pointType);
}
public int getToggleSelection(){
return 0;
}
}
My Fragment
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
assocGoalsRecyclerView.addOnItemTouchListener(RecycleTouchListener);
private RecyclerView.OnItemTouchListener RecycleTouchListener = new RecyclerView.OnItemTouchListener() {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
View child = assocGoalsRecyclerView.findChildViewUnder(e.getX(), e.getY());
if(child!=null && mGestureDetector.onTouchEvent(e)){
final int position = assocGoalsRecyclerView.getChildAdapterPosition(child);
final Goals goals = associateList.get(position);
final Categories c = categoriesList.get(position);
final int type = likeListAdapter.getToggleSelection();
return true;
}
return false;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) { }
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { }
};
I found an answer based in another responses and sugestions!!! Android: handling clicks on image view inside recycler's view item using touch framework
In My Fragment
Snippet from fragment:
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
layoutManager.scrollToPosition(0);
assocGoalsRecyclerView.setLayoutManager(layoutManager);
// assocGoalsRecyclerView.addItemDecoration(new SimpleDividerItemDecoration(getActivity()));
assocGoalsRecyclerView.setHasFixedSize(true);
likeListAdapter = new LikeListAdapter(associateList, onItemClickCallback);
assocGoalsRecyclerView.setAdapter(likeListAdapter);
public static class OnItemClickListener implements View.OnClickListener {
private int position;
private OnItemClickCallback onItemClickCallback;
public OnItemClickListener(int position, OnItemClickCallback onItemClickCallback) {
this.position = position;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public void onClick(View view) {
onItemClickCallback.onItemClicked(view, position);
}
public interface OnItemClickCallback {
void onItemClicked(View view, int position);
}
}
private OnItemClickListener.OnItemClickCallback onItemClickCallback = new OnItemClickListener.OnItemClickCallback() {
#Override
public void onItemClicked(View view, int position) {
switch(view.getId()){
case R.id.happy:
Log.e("rtetre", "happy assessed and position is = " + position);
break;
case R.id.soso:
Log.e("rwere", "soso assessed and position is = " + position);
break;
case R.id.angry:
Log.e("dfrefgt", "angry assessed and position is = " + position);
break;
}
}
};
In My adapter
public class LikeListAdapter extends RecyclerView.Adapter<LikeListAdapter.LikeItemViewHolder> {
private List<Goals> goalsList;
private LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback;
public LikeListAdapter(List<Goals> goalsList, LikeFragment.OnItemClickListener.OnItemClickCallback onItemClickCallback) {
this.goalsList = goalsList;
this.onItemClickCallback = onItemClickCallback;
}
#Override
public LikeItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View view = inflater.inflate(R.layout.recycler_item_like, parent, false);
LikeItemViewHolder likeItemViewHolder = new LikeItemViewHolder(view);
return likeItemViewHolder;
}
#Override
public void onBindViewHolder(LikeItemViewHolder holder, int position) {
final Goals goals = goalsList.get(position);
if (goals != null && getItemCount() > 0) {
holder.goalsDescriptionTextView.setText(goals.getDescription());
holder.happyButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.sosoButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
holder.angryButton.setOnClickListener(new LikeFragment.OnItemClickListener(position, onItemClickCallback));
}
}
#Override
public int getItemCount() {
return goalsList.size();
}
public static class LikeItemViewHolder extends RecyclerView.ViewHolder {
#Bind(R.id.description_goalsTextView)
TextView goalsDescriptionTextView;
#Bind(R.id.happy)
ImageView happyButton;
#Bind(R.id.soso)
ImageView sosoButton;
#Bind(R.id.angry)
ImageView angryButton;
public LikeItemViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
}