I'm trying to set up a Recyclerview with multiple lists(like Facebook ads and user feed) from 2 API endpoints but getting some errors when I try to paginate the list(load more).
Here is my code. I've tried to call the addAll method in my activity after loading the two lists from the different API endpoints but I get an error(I also call this method in my loadMore listener[paginate stuff]).
private static final int TYPE_VIDEO = 0;
private static final int TYPE_PROMOTED_VIDEO = 1;
private static final int TYPE_LOADING = 3;
private Context context;
List<Video> videosList;
List<Promoted> promotedVideosList;
private boolean isLoadingAdded = true;
public MyAdapter(Context context){
this.context = context;
//Initalization stuffs
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case TYPE_VIDEO:
View viewVideo = inflater.inflate(R.layout.item_video, parent, false);
viewHolder = new VideoVH(viewVideo);
break;
case TYPE_PROMOTED_VIDEO:
View viewPromoted = inflater.inflate(R.layout.item_promoted_video, parent, false);
viewHolder = new PromotedVH(viewPromoted);
break;
case TYPE_LOADING:
View viewLoading = inflater.inflate(R.layout.item_loading, parent, false);
viewHolder = new LoadingVH(viewLoading);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
switch (getItemViewType(position)) {
case TYPE_VIDEO:
//DO something when it a normal video
break;
case TYPE_PROMOTED_VIDEO:
//DO something when it's a promoted video
break;
case TYPE_LOADING:
//Loading view
break;
}
}
public void add(Video video, Promoted promoted) {
Toast.makeText(context, "Not Null", Toast.LENGTH_SHORT).show();
videosList.add(video);
promotedVideosList.add(promoted);
notifyItemInserted(videosList.size() + promotedVideosList.size() - 1);
}
public void addAll(List<Video> videoList, List<Promoted> promotedList) {
add(addVideo(videoList), addPromoted(promotedList));
}
private Video addVideo(List<Video> videoList){
for (Video result : videoList) return result;
return null;
}
private Promoted addPromoted(List<Promoted> promotedList{
for (Promoted result : promotedList) return result;
return null;
}
#Override
public int getItemCount() {
return videosList == null && promotedVideosList == null ? 0 : this.videosList.size() + this.promotedVideosList.size();
}
#Override
public int getItemViewType(int position) {
int videoSize = this.videosList.size();
int promotedSize = this.promotedVideosList.size();
if(position < videoSize){
return TYPE_VIDEO;
}
if(position - videoSize < promotedSize){
return TYPE_PROMOTED_VIDEO;
}
if (position == promotedSize + videoSize - 1 && isLoadingAdded){
return TYPE_LOADING;
}
return -1;
}
public static class VideoVH extends RecyclerView.ViewHolder{
VideoVH(View itemView) {
super(itemView);
//findviewbyid stuff
}
}
public static class PromotedVH extends RecyclerView.ViewHolder{
public PromotedVH(View itemView) {
super(itemView);
//findviewbyid stuff
}
}
public static class LoadingVH extends RecyclerView.ViewHolder{
#BindView(R.id.loading_progress)
ProgressBar loading;
public LoadingVH(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
}
I expected this to work but somehow it doesn't and I know I'm not doing something right.
Here is a snippet from my logcat.
java.lang.NullPointerException: Attempt to invoke interface method'boolean java.util.List.add(java.lang.Object)' on a null object reference
at com.myproject.adapters.MyAdapter.add(MyAdapter.java:508)
at com.myproject.adapters.MyAdapter.addAll(MyAdapter.java:515)
Have you initialize the lists before add data into it.In your constructor you must initialize all lists.
For Example : videosList = new List();
likewise
You are not initializing videosList and promotedVideosList . Do this
public MyAdapter(Context context){
//Initalization stuffs
this.context = context;
videosList=new ArrayList();
promotedVideosList=new ArrayList();
}
Related
I have created a recycler view and want to put two lists in it.
The first list is just a string that gets changed into fonts, which I have implemented in the onBindView method.
The second list is the cursor which includes the favorite fonts of the users.
I followed this answer on SO but I don't have any idea how I'm going to modify the getItemViewType() method so that I can get to know which list type is currently calling for view.
My adapter code
here data is the class that contains the list of fonts
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int VIEW_TYPE_TEXTVIEW = 0;
private final int VIEW_TYPE_ITEM_1 = 1;
private int total_no_of_row;
private Context context;
private String str;
private Cursor cursor;
private final LayoutInflater inflater;
public MyAdapter(Context context, int total_no_of_row, String str , Cursor cursor) {
this.context = context;
this.total_no_of_row = total_no_of_row;
this.str = str;
this.cursor = cursor;
inflater = LayoutInflater.from(context);
}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if(viewType == VIEW_TYPE_TEXTVIEW) {
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item1Holder(view);
}
else if (viewType == VIEW_TYPE_ITEM_1){
View view = inflater.inflate(R.layout.row_layout, parent, false);
return new Item2Holder(view);
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
if(holder instanceof Item1Holder){
data d = new data();
cursor.moveToPosition(position);
Log.d("this2",cursor.getInt(1)+"");
String temp = d.Convert(str, cursor.getInt(1));
((Item1Holder)holder).textView.setText(temp);
((Item1Holder)holder).rowNumber.setText("⚫");
((Item1Holder)holder).fav.setImageResource(R.drawable.ic_baseline_favorite_24);
}else if(holder instanceof Item2Holder){
data d = new data();
String temp = d.Convert(str, position);
((Item2Holder)holder).textView.setText(temp);
((Item2Holder)holder).rowNumber.setText((position + 1) + ".");
if (util.COPY) {
if (position == util.CURRENT_POSITION) {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked);
} else {
((Item2Holder)holder).imageView.setBackgroundResource(R.drawable.background_when_row_clicked_two);
}
}
}
}
#Override
public int getItemCount() {
return total_no_of_row + cursor.getCount();
}
class Item1Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item1Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
class Item2Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView , fav;
TextView rowNumber;
public Item2Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text_body);
imageView = itemView.findViewById(R.id.copy_png);
rowNumber = itemView.findViewById(R.id.row_number);
fav = itemView.findViewById(R.id.fav);
}
}
}
in main activity
here temp is the string that users want to convert into the fonts
Cursor cursor = show();
myAdapter = new MyAdapter(this , 500 , temp , cursor);
recyclerView.setAdapter(myAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
I'm not a professional android developer I'm still learning the stuff. so sorry if my code is too bad to understand
You are passing null in the onCreateViewHolder() method, and not specified position in getItemViewType() method. All you have to do is, update your code. do not pass the null value in the onCreateViewHolder method. Below code, I've tried, and works perfectly. Happy coding...
private static final int CATEGORY = 1;
private static final int NAME = 2;
private Collection<CategorizedName> data;
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof Category) {
return CATEGORY;
} else if (items.get(position) instanceof Name) {
return NAME;
}
throw new RuntimeException('error');
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (viewType) {
case CATEGORY:
View categoryView = inflater.inflate(R.layout.viewholder_category, viewGroup,
false);
viewHolder = new CategoryViewHolder(categoryView);
break;
case NAME:
View nameView = inflater.inflate(R.layout.viewholder_name, viewGroup, false);
viewHolder = new NameViewHolder(nameView);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case USER:
CategoryViewHolder categoryViewHolder = (CategoryViewHolder) viewHolder;
bindCategoryViewHolder(categoryViewHolder, position);
break;
case IMAGE:
NameViewHolder nameViewHolder = (NameViewHolder) viewHolder;
bindNameViewHolder(nameViewHolder, position);
break;
}
}
Replace your getItemViewType() with this
#Override
public int getItemViewType(int position){
if(position < total_no_of_row){
return VIEW_TYPE_TEXTVIEW;
}
if(position - total_no_of_row < cursor.getCount()){
return VIEW_TYPE_ITEM_1;
}
return -1;
}
you can also refer to my answer this
I got a weird exception in the function onCreateViewHolder inside my custom adapter. Probably because getItemViewType function returns different values as expected.
This is how getItemViewType function looks like:
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
#Override
public int getItemViewType(int position) {
if (position == 0)
return TYPE_HEADER;
return TYPE_ITEM;
}
As you can see, it returns 0 or 1 only, no other option.
This is how onCreateViewHolder function looks like:
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_groups, null);
return new HeaderHolder(view);
} else if(viewType == TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.explore_group_row, null);
return new ItemHolder(view);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " make sure your using types correctly");
}
However, I got some crashes from crashlytics that there is no type that matches with viewTypes of 6, 7, 8, 11, etc.. Not sure where it gets from...
In addition, I can't reproduce this issue, no idea how it happens.
I saw a similar issue in this thread but no solution.
Here you can see the exception from crashlytics:
Fatal Exception: java.lang.RuntimeException: there is no type that matches the type 6 make sure your using types correctly
at com.example.eliran.forum.GroupsFragment$GroupsAdapter.onCreateViewHolder(GroupsFragment.java:72)
at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:5)
at androidx.recyclerview.widget.RecyclerView$Recycler.a(RecyclerView.java:295)
at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:14)
at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:15)
at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:22)
at androidx.recyclerview.widget.GapWorker.a(GapWorker.java:3)
at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:71)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7078)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:965)
Here's the full code of the adapter:
private class GroupsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == TYPE_HEADER) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_groups, null);
return new HeaderHolder(view);
} else if(viewType == TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.explore_group_row, null);
return new ItemHolder(view);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " make sure your using types correctly");
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int i) {
if (holder instanceof ItemHolder) {
ItemHolder theHolder = (ItemHolder) holder;
Group group = groups.get(i - 1);
theHolder.title.setText(group.getTitle());
theHolder.description.setText(group.getDescription());
if(group.getImage() != null) {
Picasso.get()
.load(group.getImage())
.fit()
.into(theHolder.image);
} else {
Picasso.get()
.load(R.drawable.profile_picture_holder)
.fit()
.into(theHolder.image);
}
} else if (holder instanceof HeaderHolder){
HeaderHolder theHolder = (HeaderHolder) holder;
if (showMyGroupsPb) {
theHolder.myGroupsPb.setVisibility(View.VISIBLE);
theHolder.myGroupSectionHeader.setOnBtnListener(null);
} else {
theHolder.myGroupsPb.setVisibility(View.GONE);
theHolder.myGroupSectionHeader.setOnBtnListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(rootView.getContext(), MyGroupsActivity.class);
intent.putExtra("groups", myGroups);
startActivityForResult(intent, TheFinals.JOIN_LEAVE_GROUP_CODE);
}
});
}
}
}
#Override
public int getItemViewType(int position) {
if (position == 0)
return TYPE_HEADER;
return TYPE_ITEM;
}
#Override
public int getItemCount() {
return groups.size() + 1;
}
class HeaderHolder extends RecyclerView.ViewHolder {
private ProgressBar myGroupsPb;
private SectionHeader myGroupSectionHeader;
public HeaderHolder(View view) {
super(view);
myGroupsRv = view.findViewById(R.id.groupsRecyclerView);
myGroupsPb = view.findViewById(R.id.pb);
LinearLayoutManager horizontalLayoutManager
= new LinearLayoutManager(rootView.getContext(), LinearLayoutManager.HORIZONTAL, false);
myGroupsRv.setLayoutManager(horizontalLayoutManager);
myGroupsRv.setAdapter(myGroupAdapter);
myGroupSectionHeader = view.findViewById(R.id.myGroupSectionHeader);
}
}
class ItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView title;
protected ImageView image;
protected TextView description;
public ItemHolder(View view) {
super(view);
this.title = view.findViewById(R.id.title);
this.image = view.findViewById(R.id.image);
this.description = view.findViewById(R.id.description);
view.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int itemPosition = groupsRecyclerView.getChildLayoutPosition(view) - 1;
selectedGroupIndex = itemPosition;
Intent intent = new Intent(rootView.getContext(), GroupActivity.class);
intent.putExtra("group", groups.get(itemPosition));
startActivityForResult(intent, TheFinals.JOIN_LEAVE_GROUP_CODE);
}
}
}
I have implemented the code to show ads after every 3 item but first item it show after 4 items rest working good
Below is the code I have tried to achieve this.
I want to show ad after every 3 items.
I have taken two constant variable to manage
private class AdsAdapter extends RecyclerView.Adapter<AdsAdapter.Holder> {
List<Ads> list;
List<String> stringList;
private static final int AD_TYPE = 2;
private static final int CONTENT_TYPE = 1;
public AdsAdapter(List<Ads> list, List<String> stringList) {
this.list = list;
this.stringList = stringList;
}
#Override
public int getItemViewType(int position) {
if (position>1 && position % 4 == 0) {
return AD_TYPE;
}
return CONTENT_TYPE;
}
#NonNull
#Override
public Holder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
Log.e("TYPE", viewType + "");
View listItem;
Holder viewHolder = null;
switch (viewType) {
case AD_TYPE:
listItem =
layoutInflater.inflate(R.layout.list_item1, parent,
false);
viewHolder = new Holder(listItem);
break;
case CONTENT_TYPE:
listItem =
layoutInflater.inflate(R.layout.list_item, parent,
false);
viewHolder = new Holder(listItem);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull Holder holder, int
position) {
int viewType=getItemViewType(position);
switch (viewType)
{
case AD_TYPE:
holder.imageView.setVisibility(View.VISIBLE);
break;
case CONTENT_TYPE:
holder.textView.setVisibility(View.VISIBLE);
holder.textView.setText(stringList.get(position));
break;
}
}
#Override
public int getItemCount() {
return stringList.size();
}
public class Holder extends RecyclerView.ViewHolder {
TextView textView;
ImageView imageView;
public Holder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.tv_string);
imageView = itemView.findViewById(R.id.iv);
}
}
}
In adapter position starts from 0 so you have to do position+1
#Override
public int getItemViewType(int position) {
if (position>1 && (position+1) % 4 == 0) {
return AD_TYPE;
}
return CONTENT_TYPE;
}
I have two array list and want to set the adapter so that it looks like below screen one. But when I am setting adapter I am getting view like second screen. This is my code of Adapter:
public class ItemArrayAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final int VIEW_TYPE_MESSAGE = 0;
final int VIEW_TYPE_IMAGE = 1;
private static final String TAG = "ItemArrayAdapter";
Context context;
ArrayList<BeforLoginDao.Article> mArticleList;
ArrayList<BeforLoginDao.Quiz> mQuizList;
int i=0;
public ItemArrayAdapter(Context context,ArrayList<BeforLoginDao.Quiz> mQuizList, ArrayList<BeforLoginDao.Article> mArticleList ){
this.context = context;
this.mArticleList = mArticleList;
this.mQuizList = mQuizList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
View itemView;
if(viewType == VIEW_TYPE_MESSAGE){
itemView= LayoutInflater.from(parent.getContext()).inflate(R.layout.article_layout,parent,false);
return new ArticleViewHolder(itemView);
}
else if(viewType == VIEW_TYPE_IMAGE){
itemView= LayoutInflater.from(parent.getContext()).inflate(R.layout.quiz,parent,false);
return new QuizViewHolder(itemView);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position){
Log.e(TAG, "onBindViewHolder: " +position);
if(viewHolder instanceof ArticleViewHolder){
((ArticleViewHolder) viewHolder).populate(mArticleList.get(position));
}
else if(viewHolder instanceof QuizViewHolder){
((QuizViewHolder) viewHolder).populate(mQuizList.get(position - mArticleList.size()));
}
}
#Override
public int getItemCount(){
return mArticleList.size() + mQuizList.size();
}
#Override
public int getItemViewType(int position){
Log.e(TAG, "getItemViewType: " +position );
if(position < mArticleList.size()){
return VIEW_TYPE_MESSAGE;
}
if(position - mArticleList.size() < mQuizList.size()){
return VIEW_TYPE_IMAGE;
}
return -1;
}
public class ArticleViewHolder extends RecyclerView.ViewHolder {
public TextView mTitle, mTag1, mTag2 ;
ImageView mImageView;
public ArticleViewHolder(View itemView) {
super(itemView);
mTitle = itemView.findViewById(R.id.tv_article_title);
mTag1 = itemView.findViewById(R.id.tv_article_tag1);
mTag2 = itemView.findViewById(R.id.tv_article_tag2);
mImageView=itemView.findViewById(R.id.img_article);
}
public void populate(BeforLoginDao.Article chatWrapper){
mTitle.setText(chatWrapper.articleTitle.toString());
mTag1.setText(chatWrapper.subtag1);
mTag2.setText(chatWrapper.subtag2);
}
}
public class QuizViewHolder extends RecyclerView.ViewHolder {
public TextView tvQuizTitle, tvQuizTag1, tvQuizTag2 ;
public QuizViewHolder(View itemView) {
super(itemView);
tvQuizTitle = itemView.findViewById(R.id.tv_quiz_title);
tvQuizTag1 =itemView.findViewById(R.id.tv_quiz_tag1);
tvQuizTag2=itemView.findViewWithTag(R.id.tv_quiz_tag2);
}
public void populate(BeforLoginDao.Quiz imageDataWrapper){
Log.e(TAG, "ViewHolderTwo: " +imageDataWrapper.toString() );
tvQuizTitle.setText(imageDataWrapper.quizTitle);
tvQuizTag1.setText(imageDataWrapper.quiz_subtag1);
}
}
}
To solve this error I also checked many solution on SO.
Ref: enter link description here
Below is screen one and screen two. Screen one that I need, Screen two that I am getting.
I have a recycler view which contains multiple items and each item in the recycler view contains a horizontal recycler view.The problem I am encountering is that the layout manager is null.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
This is my code so far.I have checked that the data I am receiving is intact.
RecipeAdapter ( The main adapter )
public class RecipeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Object> items;
private final int RECIPE = 0, JOKE = 1;
public RecipeAdapter(Context context) {
this.context = context;
this.items = new ArrayList<>();
}
public void setItems(List<Object> items) {
this.items = items;
}
public void add(Object object) {
items.add(object);
notifyItemInserted(items.size());
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
final LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case RECIPE:
View recipe = inflater.inflate(R.layout.item_recipe, parent, false);
viewHolder = new ViewHolder_Recipe(recipe);
break;
case JOKE:
View joke = inflater.inflate(R.layout.item_joke, parent, false);
viewHolder = new ViewHolder_Joke(joke);
break;
default:
View recipe_default = inflater.inflate(R.layout.item_recipe, parent, false);
viewHolder = new ViewHolder_Recipe(recipe_default);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case RECIPE:
ViewHolder_Recipe viewHolderRecipe = (ViewHolder_Recipe) holder;
configureRecipeHolder(viewHolderRecipe, position);
break;
case JOKE:
ViewHolder_Joke viewHolderJoke = (ViewHolder_Joke) holder;
configureJokeHolder(viewHolderJoke, position);
break;
default:
ViewHolder_Recipe viewHolder_recipe_default = (ViewHolder_Recipe) holder;
configureRecipeHolder(viewHolder_recipe_default, position);
break;
}
}
private void configureJokeHolder(ViewHolder_Joke viewHolderJoke, int position) {
}
private void configureRecipeHolder(ViewHolder_Recipe viewHolderRecipe, int position) {
RecipeDetailed recipe = (RecipeDetailed) items.get(position);
Glide.with(context)
.load(recipe.getImage())
.into(viewHolderRecipe.getRecipe_image());
viewHolderRecipe.getRecipe_name().setText(recipe.getTitle());
viewHolderRecipe.getRecipe_prep().setText(recipe.getReadyInMinutes());
viewHolderRecipe.getRecipe_serves().setText(recipe.getServings());
viewHolderRecipe.getIngredientAdapter().setIngredients(recipe.getExtendedIngredients());
}
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof RecipeDetailed) {
return RECIPE;
} else if (items.get(position) instanceof Joke) {
return JOKE;
}
return super.getItemViewType(position);
}
#Override
public int getItemCount() {
return items.size();
}
}
The ViewHolder for that Adapter -- ViewHolder_Recipe
public class ViewHolder_Recipe extends RecyclerView.ViewHolder {
private CircularImageView recipe_image;
private TextView recipe_name;
private TextView recipe_prep;
private TextView recipe_serves;
private RecyclerView recyclerView;
private RecipeIngredientAdapter ingredientAdapter;
public ViewHolder_Recipe(View itemView) {
super(itemView);
recipe_image = (CircularImageView) itemView.findViewById(R.id.recipe_image);
recipe_name = (TextView) itemView.findViewById(R.id.recipe_name);
recipe_prep = (TextView) itemView.findViewById(R.id.recipe_prep);
recipe_serves = (TextView) itemView.findViewById(R.id.recipe_serves);
recyclerView = (RecyclerView) itemView.findViewById(R.id.recyclerView);
ingredientAdapter = new RecipeIngredientAdapter(itemView.getContext());
recyclerView.setLayoutManager(new LinearLayoutManager(itemView.getContext()
, LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(ingredientAdapter);
}
public RecipeIngredientAdapter getIngredientAdapter() {
return ingredientAdapter;
}
public CircularImageView getRecipe_image() {
return recipe_image;
}
public TextView getRecipe_name() {
return recipe_name;
}
public TextView getRecipe_prep() {
return recipe_prep;
}
public TextView getRecipe_serves() {
return recipe_serves;
}
public RecyclerView getRecyclerView() {
return recyclerView;
}
}
The child adapter -- RecipeIngredientAdapter
public class RecipeIngredientAdapter extends RecyclerView.Adapter<ViewHolderRecipeIngredient> {
private Context context;
private ArrayList<Ingredient> ingredients;
public RecipeIngredientAdapter(Context context) {
this.context = context;
}
public void setIngredients(ArrayList<Ingredient> ingredients) {
this.ingredients = ingredients;
}
#Override
public ViewHolderRecipeIngredient onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.item_recipe_ingredients, parent, false);
return new ViewHolderRecipeIngredient(view);
}
#Override
public void onBindViewHolder(ViewHolderRecipeIngredient holder, int position) {
final Ingredient ingredient = ingredients.get(position);
Glide.with(context)
.load(ingredient.getImage())
.into(holder.getIngredient_image());
}
#Override
public int getItemCount() {
return 0;
}
}
The viewholder for that is a simple viewholder which contains an image.
I have seen posts online which seem to do the exact same thing and get it working,what exactly am i missing here?
From the error, it sounds like the RecyclerView is null, not the LayoutManager. Make sure you are using the proper id from the layout. are you sure the proper layout id of the RecyclerView is R.id.recyclerView?