I'm trying to have my application display a specific layout when the arraylist PinnedSongs is empty.
I've created different viewholders and tried to inflate them depending on the PinnedSongs.size. Meaning, if it's 0, then the onCreateViewHolder should inflate a special layout. If it's different, then inflate another one.
public class RecyclerAdapterHome extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public class Viewholder extends RecyclerView.ViewHolder implements View.OnClickListener{
CardView home_cardView;
TextView home_textView;
TextView home_textView_2;
Button home_button;
Button home_button_2;
RelativeLayout parentlayout;
OnNoteListener_2 onNoteListener2;
public Viewholder(#NonNull View itemView, OnNoteListener_2 onNoteListener_2) {
super(itemView);
home_cardView = itemView.findViewById(R.id.cardview_2);
home_textView = itemView.findViewById(R.id.cardview_2_textview);
home_textView_2 = itemView.findViewById(R.id.cardview_2_textview_sub);
home_button = itemView.findViewById(R.id.play_button);
home_button_2 = itemView.findViewById(R.id.push_button);
parentlayout = itemView.findViewById(R.id.home_parentlayout);
home_button.setOnClickListener(this);
this.onNoteListener2 = onNoteListener_2;
}
#Override
public void onClick(View v) {
onNoteListener2.onClick(getAdapterPosition());
}
}
public class Viewholder_2 extends RecyclerView.ViewHolder {
TextView textView_3;
ImageView imageView;
RelativeLayout parentlayout;
public Viewholder_2(#NonNull View itemView) {
super(itemView);
textView_3 = itemView.findViewById(R.id.text_warning);
imageView = itemView.findViewById(R.id.icon);
parentlayout = itemView.findViewById(R.id.home_parentlayout);
}
}
public RecyclerAdapterHome(OnNoteListener_2 mOnNoteListener2, ArrayList<String> pinnedSongs, ArrayList<String> pinnedSongsArtists, Context mContext) {
this.mOnNoteListener2 = mOnNoteListener2;
this.PinnedSongs = pinnedSongs;
this.PinnedSongsArtists = pinnedSongsArtists;
this.mContext = mContext;
}
private ArrayList<String> PinnedSongs = new ArrayList<>();
private ArrayList<String> PinnedSongsArtists = new ArrayList<>();
private Context mContext;
private OnNoteListener_2 mOnNoteListener2;
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = null;
if (PinnedSongs.size()==0){
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nothing, parent, false);
return new Viewholder_2(v);
}else{
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.homeviewholder,
parent, false);
return new Viewholder(v,mOnNoteListener2 );
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if (PinnedSongs.size()==0){
Viewholder_2 viewholder_2 = (Viewholder_2) holder;
}else{
Viewholder viewholder = (Viewholder) holder;
viewholder.home_textView.setText(PinnedSongs.get(position));
viewholder.home_textView_2.setText(PinnedSongsArtists.get(position));
}
}
#Override
public int getItemCount() {
return PinnedSongs.size();
}
public interface OnNoteListener_2 {
void onClick(int position);
}
}
So far, the recyclerview shows nothing when the PinnedSongs list is at zero. But it shows something when it's above zero. Any idea on how I can fix it?
(I'm using the androidx libraries if it has anything to do with that).
It doesn't work because the getItemCount method returns 0 and the RecyclerView never tries to instantiate a view.
It means that onBindViewHolder is not called when the size=0.
You have different options to do it. One of these is:
#Override
public int getItemCount() {
return PinnedSongs.size() > 0 ? PinnedSongs.size() : 1;
}
#Override
public int getItemViewType(int position) {
if (PinnedSongs.size() == 0) {
return EMPTY_VIEW;
}
return super.getItemViewType(position);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if (viewType == EMPTY_VIEW) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.nothing, parent, false);
EmptyViewHolder emptyViewHolder = new EmptyViewHolder(v);
return emptyViewHolder;
}
//normal case
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.homeviewholder, parent, false);
ViewHolder viewholder = new ViewHolder(v);
return viewholder;
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
public EmptyViewHolder(View itemView) {
super(itemView);
}
}
private static final int EMPTY_VIEW = 1000;
Related
I am just practicing the RecyclerView. when I run the App my App crashed I check the log but i cant understand the problem can some help me im waiting for someone responce?
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView textView;
public ViewHolder(View view) {
super(view);
textView = (TextView) view.findViewById(R.id.name);
}
public TextView getTextView() {
return textView;
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
You need to change the following things in your code:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
//remove this from here.
//private TextView name,number;
public static class ViewHolder extends RecyclerView.ViewHolder {
//This should be from the layout you have passed in ViewHolder method. in your case from R.layout.contacx. This layout should have two textview with ids:- name and phone respectively.
private final TextView name, phone;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
phone = view.findViewById(R.id.phone);
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Create a new view, which defines the UI of the list item
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
//remvoe this from here.
//view.findViewById(R.id.name);
//view.findViewById(R.id.number);
return new ViewHolder(view);
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
//here you should call those view to bind your data like:
viewHolder.name.setText(localDataSet[position].getName());
viewHolder.phone.setText(String.valueOf(localDataSet[position].getPhone()));
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
Use ViewHolder for data bind. More safe
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {
private model[] localDataSet;
public static class ViewHolder extends RecyclerView.ViewHolder {
private final TextView name, number;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.name);
number = view.findViewById(R.id.phone);
}
public void bindData(model data) {
name.setText(data.getName());
number.setText(String.valueOf(data.getPhone()));
}
}
public CustomAdapter(model[] dataSet) {
localDataSet = dataSet;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
/* No Need
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false);
view.findViewById(R.id.name);
view.findViewById(R.id.number);
*/
return new ViewHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.contacx, viewGroup, false););
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
/*
name.setText(localDataSet[position].getName());
number.setText(localDataSet[position].getPhone());
*/
viewHolder.bindData(localDataSet[position]);
}
#Override
public int getItemCount() {
return localDataSet.length;
}
}
I'm currently building a schedule app where users can input information, and the app will organize the information in a list with each day of the week as the header with each corresponding activity under the day. I'm using a parent child recyclerview to do this (i.e. each day of the week is a part of the parent recyclerview and each activity in the schedule is part of the child recyclerview). Right now I'm trying to add a swipe to delete information in the child recyclerview. Does anyone know how I would go about doing this using the parent child recyclerview configuration, where I have two different adapters for each recyclerview?
Code for Parent RecyclerView:
public class MainRecyclerViewAdapter extends RecyclerView.Adapter<MainRecyclerViewAdapter.ViewHolder> {
ArrayList<DayHeader> weekList;
private Context mContext;
public MainRecyclerViewAdapter(Context mContext, ArrayList<DayHeader> weekList) {
this.mContext = mContext;
this.weekList = weekList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.dayofweekheader,parent,false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
DayHeader section = weekList.get(position);
String nameofday = section.getDayName();
ArrayList<medinfo> meditems = section.getmMedItems();
holder.weekdayname.setText(nameofday);
MedicationAdapter childrecyclerAdapter = new MedicationAdapter(mContext,meditems);
holder.childrecyclerview.setAdapter(childrecyclerAdapter);
}
#Override
public int getItemCount() {
return weekList.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView weekdayname;
RecyclerView childrecyclerview;
public ViewHolder(#NonNull View itemView) {
super(itemView);
weekdayname = itemView.findViewById(R.id.weekdayheader);
childrecyclerview = itemView.findViewById(R.id.childrecyclerview);
}
}
}
Code for Child RecyclerView:
public class MedicationAdapter extends RecyclerView.Adapter<MedicationAdapter.MedicationViewHolder>{
private ArrayList<medinfo> mMedList;
private Context mContext;
public static class MedicationViewHolder extends RecyclerView.ViewHolder {
public TextView mMedname;
public TextView mTime;
public TextView mNumbPills;
public ImageView popup;
public MedicationViewHolder(#NonNull View itemView) {
super(itemView);
mMedname = itemView.findViewById(R.id.medname);
mTime = itemView.findViewById(R.id.time);
mNumbPills = itemView.findViewById(R.id.numberofpills);
popup = itemView.findViewById(R.id.menumore);
}
}
public MedicationAdapter(Context mContext, ArrayList<medinfo> medList) {
this.mContext = mContext;
this.mMedList = medList;
}
#NonNull
#Override
public MedicationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.example_item,parent,false);
MedicationViewHolder mvh = new MedicationViewHolder(v);
return mvh;
}
#Override
public void onBindViewHolder(#NonNull MedicationViewHolder holder, int position) {
medinfo currentItem = mMedList.get(position);
String medName = "Medication: " + currentItem.getmMedName();
holder.mMedname.setText(medName);
String medTime = "Time: " + currentItem.getmTime();
holder.mTime.setText(medTime);
String numbPills = "# of Pills: " + currentItem.getmNumbPills();
holder.mNumbPills.setText(numbPills);
}
#Override
public int getItemCount() {
return mMedList.size();
}
public void removeItem(int position) {
mMedList.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position,mMedList.size());
}
}
I also have this SwipeItem class:
public class SwipeItem extends ItemTouchHelper.SimpleCallback {
MedicationAdapter mMedAdapter;
SwipeItem(MedicationAdapter mMedAdapter){
super(0,ItemTouchHelper.LEFT|ItemTouchHelper.RIGHT);
this.mMedAdapter = mMedAdapter;
}
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getBindingAdapterPosition();
this.mMedAdapter.removeItem(position);
}
}
So how can I implement the SwipeItem in my adapter codes to delete each child item?
I'm developping an app in which my main activity hosts different fragments via a SectionsPageAdapter. My question is about one of those fragments that roughtly looks like the image bellow:
My innerRecyclers lists differents items that I want to be able to remove by swiping and make the user validate the deletion via a DialogFragment. I was able to implement the swipe action but what I'm struggly to do is to implement a listener in the OuterRecycler for OnItemTouch so I can use an interface and send the action back to my fragment which will dispay my DialoFragment afterwards.
The code of my OuterRecycler currently looks like that:
public class OuterRecyclerAdapter extends RecyclerView.Adapter<OuterRecyclerAdapter.InsideRecyclerHolder> {
private final Context mContext;
private final String mText;
private final ArrayList<MainViewArrayListMasterList> mDataArrayList;
OuterRecyclerAdapter(Context context, ArrayList<MainViewArrayListMasterList> DataArrayList, String text) {
mContext = context;
mDataArrayList = RecyclerArrayListType;
mText = text;
}
#NonNull
#Override
public OuterRecyclerAdapter.InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(mContext);
View myOwnView = myInflater.inflate(R.layout.outer_recycler, parent, false);
return new OuterRecyclerAdapter.InsideRecyclerHolder(myOwnView);
}
#Override
public void onBindViewHolder(#NonNull OuterRecyclerAdapter.InsideRecyclerHolder holder, int position) {
MainViewArrayListMasterList currentItem = mDataArrayList.get(position);
holder.CardTitle.setText(String.valueOf(currentItem.getmYear()));
LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
holder.CardRecycler.setLayoutManager(mLayoutManager);
InnerRecyclerAdapter historyInnerView_Adapter = new InnerRecyclerAdapter(mContext, currentItem.getmArrayListStored(), mText);
new ItemTouchHelper(ListHistoryViewSwiped).attachToRecyclerView(holder.CardRecycler);
holder.CardRecycler.setAdapter(historyInnerView_Adapter);
}
#Override
public int getItemCount() {
return mDataArrayList.size();
}
static class InsideRecyclerHolder extends RecyclerView.ViewHolder {
final TextView CardTitle;
final RecyclerView CardRecycler;
InsideRecyclerHolder(#NonNull View itemView) {
super(itemView);
CardTitle = itemView.findViewById(R.id.TitleText);
CardRecycler = itemView.findViewById(R.id.Inside_Recycler);
}
}
ItemTouchHelper.SimpleCallback ListHistoryViewSwiped = new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
}
};
}
Is OnItemTouchListener the good way to acheive this ? Or do I have to create a new callback method ?
I actually circumvented this issue by calling the DialogFragment from my OuterRecycler:
public class OuterRecyclerAdapter extends RecyclerView.Adapter<OuterRecyclerAdapter.InsideRecyclerHolder> {
private final Context mContext;
private final String mText;
private final ArrayList<MainViewArrayListMasterList> mDataArrayList;
private FragmentManager mFragmentManager;
OuterRecyclerAdapter(Context context, FragmentManager FragmentManager, ArrayList<MainViewArrayListMasterList> DataArrayList, String text) {
mContext = context;
mFragmentManager = FragmentManager;
mDataArrayList = RecyclerArrayListType;
mText = text;
}
#NonNull
#Override
public OuterRecyclerAdapter.InsideRecyclerHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater myInflater = LayoutInflater.from(mContext);
View myOwnView = myInflater.inflate(R.layout.outer_recycler, parent, false);
return new OuterRecyclerAdapter.InsideRecyclerHolder(myOwnView);
}
#Override
public void onBindViewHolder(#NonNull OuterRecyclerAdapter.InsideRecyclerHolder holder, int position) {
MainViewArrayListMasterList currentItem = mDataArrayList.get(position);
holder.CardTitle.setText(String.valueOf(currentItem.getmYear()));
LinearLayoutManager mLayoutManager = new LinearLayoutManager(mContext, LinearLayoutManager.VERTICAL, false);
holder.CardRecycler.setLayoutManager(mLayoutManager);
InnerRecyclerAdapter historyInnerView_Adapter = new InnerRecyclerAdapter(mContext, currentItem.getmArrayListStored(), mText);
new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
#Override
public boolean onMove(#NonNull RecyclerView recyclerView, #NonNull RecyclerView.ViewHolder viewHolder, #NonNull RecyclerView.ViewHolder target) {
return false;
}
#Override
public void onSwiped(#NonNull RecyclerView.ViewHolder viewHolder, int direction) {
openMyDialog(currentItem.getmArrayListStored().get(viewHolder.getAdapterPosition()));
}
}).attachToRecyclerView(holder.CardRecycler);
holder.CardRecycler.setAdapter(historyInnerView_Adapter);
}
#Override
public int getItemCount() {
return mDataArrayList.size();
}
static class InsideRecyclerHolder extends RecyclerView.ViewHolder {
final TextView CardTitle;
final RecyclerView CardRecycler;
InsideRecyclerHolder(#NonNull View itemView) {
super(itemView);
CardTitle = itemView.findViewById(R.id.TitleText);
CardRecycler = itemView.findViewById(R.id.Inside_Recycler);
}
}
private void openMyDialog(MainViewArrayListRecycler itemToDelete) {
MyDialog myDialog = MyDialog.newInstance(itemToDelete);
myDialog.show(mFragmentManager, "MyDialogDialog");
}
}
I have a problem with my code, I created two adapter within one recyclerview. I put them both in a class, and I need this adapter to return an Viewholder depending on some situations.
Here is my Adapter code:
public class CurrentUserTaskListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public List<Task> taskList;
private static final int ITEM_TYPE_PUBLISHED_TASK = 1;
private static final int ITEM_TYPE_ASSIGNED_TASK = 2;
public CurrentUserTaskListAdapter(List<Task> taskList) {
this.taskList = taskList;
}
public class AssignedTaskViewHolder extends RecyclerView.ViewHolder {
View mView;
public TextView tvTagAndDate;
public TextView tvStatus;
public AssignedTaskViewHolder(View itemView) {
super(itemView);
mView = itemView;
tvTagAndDate = itemView.findViewById(R.id.tvTagAndDate);
tvStatus = itemView.findViewById(R.id.tvStatus);
}
}
public class PublishedTaskViewHolder extends RecyclerView.ViewHolder {
View mView;
public TextView tvTagAndDate;
public TextView tvStatus;
public PublishedTaskViewHolder(View itemView) {
super(itemView);
mView = itemView;
tvTagAndDate = itemView.findViewById(R.id.tvTagAndDate);
tvStatus = itemView.findViewById(R.id.tvStatus);
}
}
#Override
public int getItemViewType(int position) {
if (taskList.get(position).getAssignedTo() == null)
return ITEM_TYPE_PUBLISHED_TASK;
else
return ITEM_TYPE_ASSIGNED_TASK;
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
if(i == ITEM_TYPE_ASSIGNED_TASK){
layoutInflater.inflate(R.layout.layout_curent_user_assigned_tasks_item, viewGroup, false);
return new AssignedTaskViewHolder(viewGroup);
}
else if (i == ITEM_TYPE_PUBLISHED_TASK){
layoutInflater.inflate(R.layout.layout_current_user_pending_tasks, viewGroup, false);
return new PublishedTaskViewHolder(viewGroup);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
if(viewHolder instanceof AssignedTaskViewHolder){
final AssignedTaskViewHolder assignedTaskViewHolder = (AssignedTaskViewHolder) viewHolder;
}
else if (viewHolder instanceof PublishedTaskViewHolder) {
final PublishedTaskViewHolder publishedTaskViewHolder = (PublishedTaskViewHolder) viewHolder;
}
}
#Override
public int getItemCount() {
return taskList.size();
}}
The problem i have is that i get this error:
java.lang.IllegalStateException: ViewHolder views must not be attached when created. Ensure that you are not passing 'true' to the attachToRoot parameter of LayoutInflater.inflate(..., boolean attachToRoot)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6796)
at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5975)
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)....and so on
In the method getItemViewType i verify which TYPE an object from my list is.
Fix this part it is in example:
if (i == ITEM_TYPE_ASSIGNED_TASK) {
View view = layoutInflater.inflate(R.layout.layout_curent_user_assigned_tasks_item, viewGroup, false);
return new AssignedTaskViewHolder(view);
} else if (i == ITEM_TYPE_PUBLISHED_TASK) {
View view = layoutInflater.inflate(R.layout.layout_current_user_pending_tasks, viewGroup, false);
return new PublishedTaskViewHolder(view);
}
Problem is that you are passing parent layout where ViewHolder's item layout should be.
Good luck!
I tried to insert recycleview inside cardview, but it not create it. I think it's problem with adapter, because this type of card created, but not fill recycle view.Now its look like this
There's my recycleview adapter code
public class SubItemsAdapter extends RecyclerView.Adapter<SubItemsAdapter.SubtasksViewHolder>{
private List<Subtask> subtasks;
public SubItemsAdapter(List<Subtask> subtasks){
this.subtasks = subtasks;
}
public class SubtasksViewHolder extends RecyclerView.ViewHolder{
TextView titleTextView;
CheckBox doneCheckBox;
public SubtasksViewHolder(View itemView) {
super(itemView);
titleTextView = (TextView)itemView.findViewById(R.id.subtaskTitle);
doneCheckBox = (CheckBox)itemView.findViewById(R.id.subtaskCheckbox);
}
}
#Override
public SubtasksViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.subtasks_listitem,parent,false);
return new SubtasksViewHolder(v);
}
#Override
public void onBindViewHolder(SubtasksViewHolder holder, int position) {
holder.titleTextView.setText(subtasks.get(position).getText());
holder.doneCheckBox.setChecked(subtasks.get(position).getDone());
}
#Override
public int getItemCount() {
return subtasks.size();
}} `
And my cardview code:
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder> {
ArrayList<TodoItem> todoItems;
int[] dataTypes;
private static final int SIMPLETODOITEM = 0;
private static final int EXTENDTODOITEM = 1;
Context context;
public TasklistAdapter(ArrayList<TodoItem> todoItems, int[] dataTypes, Context context)
{
this.todoItems = todoItems;
this.dataTypes = dataTypes;
this.context = context;
}
public class SimpleViewHolder extends ViewHolder{
TextView titleTextView;
TextView desciptionTextView;
CheckBox doneCheckBox;
public SimpleViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.simpleitem_title_textbox);
desciptionTextView =(TextView)v.findViewById(R.id.simpleitem_description_textbox);
doneCheckBox = (CheckBox)v.findViewById(R.id.simpleitem_checkbox);
}
}
public class ExtendViewHolder extends ViewHolder{
TextView titleTextView;
TextView descTextView;
RecyclerView subtasksListView;
SubItemsAdapter adapter;
RecyclerView.LayoutManager manager;
public ExtendViewHolder(View v) {
super(v);
titleTextView = (TextView)v.findViewById(R.id.extended_card_title);
descTextView = (TextView)v.findViewById(R.id.extended_card_description);
subtasksListView = (RecyclerView)v.findViewById(R.id.subtasks_listview);
manager = new LinearLayoutManager(v.getContext());
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType)
{
case EXTENDTODOITEM:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.extendedtodoitem_card, parent, false);
return new ExtendViewHolder(v);
default:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.simpletodoitem_card,parent,false);
return new SimpleViewHolder(v);
}
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
switch (holder.getItemViewType()){
case EXTENDTODOITEM:
ExtendViewHolder extViewHold = (ExtendViewHolder)holder;
extViewHold.adapter = new SubItemsAdapter(todoItems.get(position).getSubtasks());
extViewHold.titleTextView.setText(todoItems.get(position).getText());
extViewHold.descTextView.setText(todoItems.get(position).getDescription());
extViewHold.subtasksListView.setLayoutManager(extViewHold.manager);
extViewHold.subtasksListView.setAdapter(extViewHold.adapter);
break;
default:
SimpleViewHolder simViewHold = (SimpleViewHolder)holder;
simViewHold.desciptionTextView.setText(todoItems.get(position).getDescription());
simViewHold.titleTextView.setText(todoItems.get(position).getText());
break;
}
}
#Override
public int getItemCount() {
return todoItems.size();
}
#Override
public int getItemViewType(int position) {
return dataTypes[position];
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View v) {
super(v);
}
}
}`
in your TasklistAdapter, static class ViewHolder extending RecyclerView.ViewHolder seems useless! and you are trying to inflate and bind data with two heterogeneous layouts with their own viewholder sub-classes! My solution would be to change this :
public class TasklistAdapter extends RecyclerView.Adapter<TasklistAdapter.ViewHolder>
to
public class TasklistAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>