(Tho i am working with Xamarin(C#), the codes or the structure should seem identical to Java.)
So, in an Activity, i have a ViewPager and a TabLayout. Inside the ViewPager, there's a Fragment, which contains a RecyclerView inside a NestedScrollView.
I have two different layouts and i want to display them in the RecyclerView. After doing some research, this is what i ended up with :
Created two ViewHolder(s)
public class PostRegularViewHolder : RecyclerView.ViewHolder
{
public ImageView userImg { get; set; }
public TextView userFullName { get; set; }
public PostRegularViewHolder(View itemView) : base(itemView)
{
userImg = itemView.FindViewById<ImageView>(Resource.Id.feed_user_image);
userFullName = itemView.FindViewById<TextView>(Resource.Id.username);
}
}
public class CreatePostViewHolder : RecyclerView.ViewHolder
{
public ImageView userImg { get; set; }
public TextView userFirstName { get; set; }
public CreatePostViewHolder(View itemView) : base(itemView)
{
userImg = itemView.FindViewById<ImageView>(Resource.Id.topBar_user_image);
userFirstName = itemView.FindViewById<TextView>(Resource.Id.user_headerbar_title);
}
}
Inside the Adapter, i have:
public override int ItemCount
{
get
{
if (postCollection != null)
{
return postCollection.Count;
}
return 1; //Couldn't figure out what to return, so returned 1.
}
}
public PostRegularAdapter(List<PostRegular> postList = null, string userFirstName = null)
{
if (postList != null)
{
postCollection = postList;
}
UserFirstName = userFirstName;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
if (postCollection == null)
{
RecyclerView.ViewHolder vh = new CreatePostViewHolder(LayoutInflater.From(parent.Context).Inflate(Resource.Layout.customview_user_writepostbar, parent, false));
return vh;
}
else
{
RecyclerView.ViewHolder vh2 = new PostRegularViewHolder(LayoutInflater.From(parent.Context).Inflate(Resource.Layout.customview_postregular, parent, false));
return vh2;
}
}
Inside my Fragment, i have:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mainView = ///Inflated the mainview
var layoutManager = new LinearLayoutManager(Context, LinearLayoutManager.Vertical, false);;
recyclerView.SetLayoutManager(layoutManager);
recyclerView.SetAdapter(postRegularAdapter);
postRegularAdapter = new PostRegularAdapter(userFirstName: "Aousaf");
recyclerView.SetItemAnimator(new DefaultItemAnimator());
return mainView;
}
Here, in the OnCreateView method of the Fragment, i add the first view to the RecyclerView. To add the other view, i have this method inside the fragment :
public void PopulateWithPosts()
{
List<PostRegular> posts = new List<PostRegular>();
posts.Add(new PostRegular() { //passing the properties here });
postRegularAdapter.postCollection = posts;
postRegularAdapter.NotifyItemInserted(posts.Count - 1);
postRegularAdapter.NotifyDataSetChanged();
}
}
I call the PopulateWithPosts method from my activity, inside the OnTabSelected event of the TabLayout.
The problem here is that, the OnCreateViewHolder is not being called when i call the PopulateWithPosts method, or to narrow down, when i call the NotifyDataSetChanged method. What i can see using the debugger is that, OnCreateViewHolder is not called, rather, OnBindViewHolder is called.
The OnBindViewHolder method
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
if (postCollection == null)
{
CreatePostViewHolder vh2 = holder as CreatePostViewHolder;
vh2.userFirstName.Text = UserFirstName + ", share something inspiring!";
}
else
{
PostRegularViewHolder vh = holder as PostRegularViewHolder;
//Working with the viewHolder...
}
According to the logic, the else block gets executed, however, as OnCreateViewHolder was not called this time, the holder remains CreatePostViewHolder aka the previous ViewHolder, which results in the cast failing, so i end up with vh being null.
I am a little puzzled here. Is there a way to call the OnCreateViewHolder when needed? Am i going in the right direction with adding multiple VIewHolders to a RecyclerView ? What am i missing here ?