Related
I'm desperate.
I have a nested recycler view. Each outer element has an array of inner elements. A different adapter has been created for the inner elements. I am creating an array of external elements of class "KairosWithEvents", each of which contains internal elements of class "Event". Everything is displayed well. When elements are added, everything is also updated. For testing, I created two objects of the "KairosWithEvent" class. In the first object I have placed two objects of the "Event" class, and in the second - three objects. But when I want to change the EditText value, the keyboard appears. And the last element of the second object appears in the first object. How can I fix it? Objects are not moved or duplicated, but showed incorrectly.
This is what a nestled recycler view looks like initially.
And this is what a nested recycler view looks like after the keyboard appears. The "Эвент5" element is duplicated to the first element for some reason.
Here's my code: Outer Adapter:
public class EventAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static List<Item> items;
private static RecyclerViewClickInterface listener;
private RecyclerView.RecycledViewPool sharedPool = new RecyclerView.RecycledViewPool();
private Context context;
public EventAdapter() {
items = new ArrayList<>();
this.context = context;
}
public EventAdapter(List<Item> newItems){
items = newItems;
}
class KairosViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
private TextView title;
private CheckBox iv;
private RecyclerView rv;
public KairosViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv);
iv = itemView.findViewById(R.id.iv);
rv = itemView.findViewById(R.id.rvSteaks);
itemView.setBackgroundColor(Color.parseColor("#91b3f2"));
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
}
#RequiresApi(api = Build.VERSION_CODES.N)
void bind(KairosWithEvents kairosWithEvents){
title.setText(kairosWithEvents.kairos.kairosId + " = " + kairosWithEvents.kairos.title);
LinearLayoutManager layoutManager = new LinearLayoutManager(
rv.getContext(),
LinearLayoutManager.VERTICAL,
false);
List<Item> itemsEvents = new ArrayList<>();
kairosWithEvents.events.forEach(i -> itemsEvents.add(new Item(Constants.EVENT_KAIROS, i)));
SubAdapter childAdapter = new SubAdapter(itemsEvents);
rv.setLayoutManager(layoutManager);
rv.setAdapter(childAdapter);
rv.setRecycledViewPool(sharedPool);
}
#Override
public void onClick(View view) {
int position = getAdapterPosition();
if (listener != null && position != RecyclerView.NO_POSITION){
listener.onItemKairosWithEvents( ((KairosWithEvents) items.get(position).object) );
}
}
#Override
public boolean onLongClick(View view) {
return false;
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
switch (viewType){
case Constants.KAIROS:
return new KairosViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_ex, parent, false));
}
return null;
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)){
case Constants.KAIROS:
KairosWithEvents kairos = ((KairosWithEvents) items.get(position).object);
((KairosViewHolder) holder).bind(kairos);
break;
}
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public int getItemViewType(int position) {
return items.get(position).type;
}
}
Inner Adapter:
public class SubAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static List<Item> items;
public SubAdapter(List<Item> newItems) {
items = newItems;
}
static class EventViewHolder extends RecyclerView.ViewHolder {
private TextView title;
public EventViewHolder(#NonNull View itemView) {
super(itemView);
title = itemView.findViewById(R.id.tv);
itemView.setBackgroundColor(Color.parseColor("#ffc8a8"));
}
void bind(Event event){
title.setText(event.eventId + " = " + event.title);
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
switch (viewType) {
case Constants.EVENT_KAIROS:
return new EventViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_sub, parent, false));
}
return null;
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
switch (getItemViewType(position)){
case Constants.EVENT_KAIROS:
Event event = (Event) items.get(position).object;
((EventViewHolder) holder).bind(event);
break;
}
}
#Override
public int getItemCount() {
return items.size();
}
#Override
public int getItemViewType(int position) {
return items.get(position).type;
}
}
In SubAdapter, remove the static keyword from your items field:
private static List<Item> items;
Should be this instead:
private List<Item> items;
You should make the same change to your outer adapter, but since there's only one of them at a time it doesn't wind up causing issues.
I am developing an app in which we need vertical Recyclerview inside horizontal Recyclerview. And the vertical Recyclerview have multiple view types. So the problem is, when i scroll down few items and go back up again, only the nested recyclerview is populated with wrong data. Otherwise every other data is correct.
Like in this picture you can see the correct data where recyclerview is gone
In this picture you can see the recyclerview is populated with some other object data and showing image when i scroll back up
Now i have tried everything setHasStableIds(true) , using same viewpool worsen the situation,getItemId();
But nothing seems to work.
OUTER RECYCLERVIEW ADAPTER
private ArrayList<BasePostData> basePostDataArrayList;
private Context mContext;
private RecyclerView.RecycledViewPool viewPool;
public PostFragmentListAdapter(ArrayList<BasePostData> basePostDataArrayList, Context mContext) {
this.basePostDataArrayList = basePostDataArrayList;
this.mContext = mContext;
setHasStableIds(true);
}
public static class MyviewHolder extends RecyclerView.ViewHolder{
ImageView profileImage,more;
TextView name,user_category,post_category,follow,like,comment,share,description,post_type,highlight;
RecyclerView recyclerView;
HorizontalPostRecyclerview horizontalAdapter;
public MyviewHolder(#NonNull View itemView) {
super(itemView);
Context context = itemView.getContext();
this.comment = itemView.findViewById(R.id.post_comment_textview);
this.name = itemView.findViewById(R.id.post_user_name);
this.user_category = itemView.findViewById(R.id.post_category);
this.post_category = itemView.findViewById(R.id.posts_multiple_categories);
this.follow = itemView.findViewById(R.id.post_follow_button);
this.like = itemView.findViewById(R.id.post_like_textview);
this.share = itemView.findViewById(R.id.post_whatsapp_tv);
this.profileImage = itemView.findViewById(R.id.post_profile_pic);
this.more = itemView.findViewById(R.id.post_more_tv);
this.description = itemView.findViewById(R.id.post_description_textview);
this.recyclerView =itemView.findViewById(R.id.post_content_recyclerview);
this.post_type= itemView.findViewById(R.id.post_type);
this.highlight= itemView.findViewById(R.id.post_highlighted);
// recyclerView = (RecyclerView) itemView.findViewById(R.id.horizontal_list);
}
}
#NonNull
#Override
public MyviewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.post_layout,viewGroup,false);
MyviewHolder myviewHolder = new MyviewHolder(view);
return myviewHolder;
}
#Override
public void onBindViewHolder(#NonNull MyviewHolder viewHolder, int position)
{
StringBuilder post_cat= new StringBuilder();
BasePostData basePostData = basePostDataArrayList.get(position);
viewHolder.description.setText(basePostData.getDiscription());
viewHolder.name.setText(basePostData.getUser());
viewHolder.post_type.setText(basePostData.getPost_type());
viewHolder.itemView.setTag(position);
if (basePostData.getUser_category()!=null){
viewHolder.user_category.setText("("+basePostData.getUser_parent_category()+") "+basePostData.getUser_category());
}else {
viewHolder.user_category.setText(basePostData.getUser_parent_category());
}
viewHolder.like.setText(String.valueOf(basePostData.getLike())+" Likes");
viewHolder.comment.setText(String.valueOf(basePostData.getTotal_comments())+" Comments");
for (int i = 0;i<basePostData.getPost_tag().size();i++)
{
post_cat.append(basePostData.getPost_tag().get(i).getTag()).append(" | ");
}
viewHolder.post_category.setText(post_cat.toString());
Picasso.get()
.load(basePostData.getUser_profile_pic())
.placeholder(R.drawable.profile_ic)
.error(R.drawable.profile_ic)
.into(viewHolder.profileImage);
//--------------------------------highlight answer--------------
if (basePostData.getHighlight_comment()!=null)
{
viewHolder.highlight.setVisibility(View.VISIBLE);
viewHolder.highlight.setText(basePostData.getHighlight_comment().getComment());
}
//---------------------------recyclerview for files-------------------------------
if (basePostData.getFile_type()!=null) {
viewHolder.recyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
viewHolder.horizontalAdapter = new HorizontalPostRecyclerview();
viewHolder. recyclerView.setAdapter(viewHolder.horizontalAdapter);
viewHolder.horizontalAdapter.setData(basePostData.getPost_file()); // List of Strings
viewHolder.horizontalAdapter.setRowIndex(position);
viewHolder.recyclerView.setVisibility(View.VISIBLE);
/*
Log.e("item ",basePostData.getFile_type());
viewHolder. recyclerView.setLayoutManager(new LinearLayoutManager(mContext, LinearLayoutManager.HORIZONTAL, false));
*//* switch (basePostData.getFile_type()){
case "Image":
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_IMAGE);
viewHolder. recyclerView.setAdapter(viewHolder.horizontalAdapter);
break;
case "Video":
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_VIDEO);
viewHolder. recyclerView.setAdapter(viewHolder.horizontalAdapter);
break;
case "Document":
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_DOC);
viewHolder. recyclerView.setAdapter(viewHolder.horizontalAdapter);
viewHolder.horizontalAdapter.setRowIndex(position);
break;
}*//*
if (basePostData.getFile_type().equalsIgnoreCase("image")){
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_IMAGE);
}else if (basePostData.getFile_type().equalsIgnoreCase("video")){
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_VIDEO);
}else if (basePostData.getFile_type().equalsIgnoreCase("document"))
viewHolder. horizontalAdapter = new HorizontalPostRecyclerview(basePostData.getPost_file() ,mContext,ConstantsOSH.TYPE_DOC);
viewHolder. recyclerView.setAdapter(viewHolder.horizontalAdapter);
viewHolder.horizontalAdapter.setRowIndex(position);
*/ }
}
#Override
public int getItemCount() {
return basePostDataArrayList.size();
}
public void add(ArrayList<BasePostData> basePostDatalist) {
basePostDataArrayList.addAll(basePostDatalist);
notifyDataSetChanged();
}
public void clear() {
basePostDataArrayList.clear();
notifyDataSetChanged();
}
#Override
public long getItemId(int position) {
BasePostData product = basePostDataArrayList.get(position);
return product.hashCode();
}
}
VERTICAL NESTED RECYCLERVIEW ADAPTER
public class HorizontalPostRecyclerview extends
RecyclerView.Adapter<RecyclerView.ViewHolder> {
private ArrayList<PostFileModel> dataset;
private Context mContext;
private int mRowIndex = -1;
private int viewType;
public HorizontalPostRecyclerview() {
setHasStableIds(true);
}
public HorizontalPostRecyclerview(ArrayList<PostFileModel> dataset, Context mContext) {
this.dataset = dataset;
this.mContext = mContext;
}
public HorizontalPostRecyclerview(ArrayList<PostFileModel> dataset, Context mContext,int viewType) {
this.dataset = dataset;
this.mContext = mContext;
this.viewType = viewType;
}
public void setRowIndex(int index) {
mRowIndex = index;
}
public void setData(ArrayList<PostFileModel> data) {
if (dataset != data) {
dataset = data;
notifyDataSetChanged();
}
}
private class ImageViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView,play_btn;
private TextView name;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.horizontal_image_layout_imageview);
// name = itemView.findViewById(R.id.post_image_gallery_name_text);
// play_btn = itemView.findViewById(R.id.post_image_gallery_play_btn);
}
}
private class VideoViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView,play_btn;
private TextView name;
public VideoViewHolder(View itemView) {
super(itemView);
imageView = itemView.findViewById(R.id.horizontal_video_layout_imageview);
// name = itemView.findViewById(R.id.post_image_gallery_name_text);
play_btn = itemView.findViewById(R.id.horizontal_video_layout_play_btn);
}
}
private class DocViewHolder extends RecyclerView.ViewHolder {
private ImageView imageView,play_btn;
private TextView name;
public DocViewHolder(View itemView) {
super(itemView);
//imageView = itemView.findViewById(R.id.post_image_gallery_imageview);
name = itemView.findViewById(R.id.horizontal_doc_layout_textview);
play_btn = itemView.findViewById(R.id.horizontal_doc_layout_playbtn);
}
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View itemView;
// ImageViewHolder holder = new ImageViewHolder(itemView);
switch (i)
{
case ConstantsOSH.TYPE_IMAGE:
itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.horizontal_post_image_layout,viewGroup, false);
return new ImageViewHolder(itemView);
// break;
case ConstantsOSH.TYPE_DOC:
itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.horizontal_post_doc_layout,viewGroup, false);
return new DocViewHolder(itemView);
// break;
case ConstantsOSH.TYPE_VIDEO:
itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.horizontal_post_video_layout,viewGroup, false);
return new VideoViewHolder(itemView);
// break;
default:
itemView = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.horizontal_post_image_layout,viewGroup, false);
return new ImageViewHolder(itemView);
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder viewHolder, int i) {
// ImageViewHolder holder = (ImageViewHolder) viewHolder;
switch (dataset.get(i).getFile_type()){
case "Image":
ImageViewHolder holder = (ImageViewHolder) viewHolder;
Picasso.get().load(dataset.get(i).getFile()).error(R.drawable.camera_ic).placeholder(R.drawable.flag_india).into(holder.imageView);
holder.itemView.setTag(i);
/* Glide.with(holder.imageView.getContext()) // Bind it with the context of the actual view used
.load(dataset.get(i).getFile()) // Load the image
.thumbnail(0.2f) // make use of the thumbnail which can display a down-sized version of the image
.into(holder.imageView);
*/
break;
case "document":
DocViewHolder holder2 = (DocViewHolder) viewHolder;
holder2.play_btn.setImageResource(R.drawable.doc_ic_new);
holder2.play_btn.setVisibility(View.VISIBLE);
String[] split = dataset.get(i).getFile().split("post_file/");
holder2.name.setText(split[1]);
holder2.name.setVisibility(View.VISIBLE);
holder2.itemView.setTag(i);
break;
case "video":
VideoViewHolder holder3 = (VideoViewHolder) viewHolder;
long interval = 2000;
RequestOptions options = new RequestOptions().frame(interval).placeholder(R.drawable.camera_ic);
Glide.with(holder3.imageView.getContext()).asBitmap()
.load(dataset.get(i).getFile())
.apply(options)
.into(holder3.imageView);
holder3.play_btn.setVisibility(View.VISIBLE);
holder3.itemView.setTag(i);
break;
}
}
#Override
public int getItemCount() {
return dataset.size();
}
#Override
public long getItemId(int position) {
PostFileModel postFileModel = dataset.get(position);
return postFileModel.hashCode();
}
#Override
public int getItemViewType(int position) {
switch (dataset.get(position).getFile_type()) {
case "Image":
return ConstantsOSH.TYPE_IMAGE;
case "video":
return ConstantsOSH.TYPE_VIDEO;
case "document":
return TYPE_DOC;
default:
return -1;
}
}
}
Here is what I have achieved ? 3 different sections, 10 different items in each section.
Here is the tutorial link I am following and below is the Screenshot:
Trying to show different Views for each and every Section. Like:
For Section 1 (layout_1.xml)
For Section 2 (layout_2.xml)
For Section 3 (layout_3.xml)
But showing layout view of layout_1.xml in every Section... (Section 1, 2, 3)
May I know where I am doing mistake in my code, what I have missed ?
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private ArrayList<SingleItemModel> itemsList;
private Context mContext;
public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList) {
this.itemsList = itemsList;
this.mContext = context;
}
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
switch (i) {
case 0:
View viewONE = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_1, null, false);
SingleItemRowHolder rowONE = new SingleItemRowHolder(viewONE);
return rowONE;
case 1:
View viewTWO = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_2, null, false);
SingleItemRowHolder rowTWO = new SingleItemRowHolder(viewTWO);
return rowTWO;
case 2:
View viewTHREE = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_3, null, false);
SingleItemRowHolder rowTHREE = new SingleItemRowHolder(viewTHREE);
return rowTHREE;
}
return null;
}
#Override
public void onBindViewHolder(SingleItemRowHolder holder, int i) {
SingleItemModel singleItem = itemsList.get(i);
holder.tvTitle.setText(singleItem.getName());
}
#Override
public int getItemCount() {
return (null != itemsList ? itemsList.size() : 0);
}
public class SingleItemRowHolder extends RecyclerView.ViewHolder {
protected TextView tvTitle;
protected ImageView itemImage;
public SingleItemRowHolder(View view) {
super(view);
this.tvTitle = (TextView) view.findViewById(R.id.tvTitle);
this.itemImage = (ImageView) view.findViewById(R.id.itemImage);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
Use this inside adapter's getItemViewType:
#Override
public int getItemViewType(int position) {
if (position == 0) {
return 0;
} else if(position == 1) {
return 1;
} else {
return 2;
}
}
to use multiple layouts according to position in recyclerview you have to override the getItemViewType(int position) method inside the adapter :-
#Override
public int getItemViewType(int position) {
if(position==0)
return 0;
else if(position==1)
return 1;
else
return 2;
}
FYI
RecyclerView can also be used to inflate multiple view types .
It will be easiest for you that create different Holder.
Create Different Adapter is best Solutions
Try with
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
switch (i) {
case 0:
View viewONE = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_1, null, false);
SingleItemRowHolder rowONE = new SingleItemRowHolder(viewONE);
return rowONE;
case 1:
View viewTWO = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_2, null, false);
SingleItemRowHolderTwo rowTWO = new SingleItemRowHolderTwo (viewTWO);
return rowTWO;
case 2:
View viewTHREE = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_3, null, false);
SingleItemRowHolderThree rowTHREE = new SingleItemRowHolderThree(viewTHREE);
return rowTHREE;
}
return null;
}
Read RecyclerView can also be used to inflate multiple view types
As it was mention already, in order to getItemViewType method of RecyclerView.Adapter class, because if you will see in implementation of that method, you will see that it just return 0 all the time.
public int getItemViewType(int position) {
return 0;
}
And here adjusted code of your adapter which should solve your problem.
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private static final int ITEM_TYPE_ROW_1 = 0;
private static final int ITEM_TYPE_ROW_2 = 1;
private static final int ITEM_TYPE_ROW_3 = 2;
private ArrayList<SingleItemModel> itemsList;
private Context context;
public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList) {
this.itemsList = itemsList;
this.context = context;
}
#Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return ITEM_TYPE_ROW_1;
case 1:
return ITEM_TYPE_ROW_2;
case 2:
return ITEM_TYPE_ROW_3;
}
throw new RuntimeException(String.format("unexpected position - %d", position));
}
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
switch (viewType) {
case ITEM_TYPE_ROW_1:
View viewOne = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_1, null, false);
return new SingleItemRowHolder(viewOne);
case ITEM_TYPE_ROW_2:
View viewTwo = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_2, null, false);
return new SingleItemRowHolder(viewTwo);
case ITEM_TYPE_ROW_3:
View viewThree = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.layout_3, null, false);
return new SingleItemRowHolder(viewThree);
}
throw new RuntimeException(String.format("unexpected viewType - %d", viewType));
}
#Override
public void onBindViewHolder(SingleItemRowHolder holder, int i) {
SingleItemModel singleItem = itemsList.get(i);
holder.tvTitle.setText(singleItem.getName());
}
#Override
public int getItemCount() {
return (null != itemsList ? itemsList.size() : 0);
}
class SingleItemRowHolder extends RecyclerView.ViewHolder {
TextView tvTitle;
ImageView itemImage;
public SingleItemRowHolder(View view) {
super(view);
this.tvTitle = (TextView) view.findViewById(R.id.tvTitle);
this.itemImage = (ImageView) view.findViewById(R.id.itemImage);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), tvTitle.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
}
You can do it in a more simple way. Pass any flag while initializing adapter.
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private ArrayList<SingleItemModel> itemsList;
private Context context;
private int view;
public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList, int layoutFlag) {
this.itemsList = itemsList;
this.context = context;
switch(layoutFlag) {
case 0:
view = R.layout.layout_1;
break;
case 1:
view = R.layout.layout_2;
break;
case 2:
view = R.layout.layout_3;
break;
}
}
...
...
...
}
Use this view for layout reference. You just have to tell which layout to be inflated at the time of setting adapter.
You need to override the method
int getItemViewType (int position)
It receives the row number and you need to return the "type" of row i.e. 1 2 or 3.
The result will then be passed to onCreateViewHolder.
If for example you want to show this list of views:
type1
type2
type3
type1
type2
type3
then that should do the work:
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private static final int ITEM_TYPE_ROW_1 = 0;
private static final int ITEM_TYPE_ROW_2 = 1;
private static final int ITEM_TYPE_ROW_3 = 2;
private ArrayList<SingleItemModel> itemsList;
private Context context;
private ArrayList<Integer> viewTypes = new ArrayList<>();
public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList) {
this.itemsList = itemsList;
this.context = context;
viewTypes.add(ITEM_TYPE_ROW_1);
viewTypes.add(ITEM_TYPE_ROW_2);
viewTypes.add(ITEM_TYPE_ROW_3);
viewTypes.add(ITEM_TYPE_ROW_1);
viewTypes.add(ITEM_TYPE_ROW_2);
viewTypes.add(ITEM_TYPE_ROW_3);
}
#Override
public int getItemViewType(int position) {
return viewTypes.get(position);
}
#Override
public int getItemCount() {
return viewTypes.size();
}
.......
........
If you want to add/remove rows then it can be done inserting/removing viewTypes in the viewTypes Array and then calling RecyclerView notifyItemInserted or notifyItemRemoved methods the list will be updated with the new order and type of views.
Simply use frame layout with your fragment and add this fragment in your framelayout that will add like you want for that. So its also easy to handle. hope this will help you
Yes you need to override getItemViewType(int position) method which helps to inflate different views in recyclerview.
I am posting a sample code which may help you.
public class TransactionHistoryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private final int TYPE_HEADER = 1;
private final int TYPE_CHILD = 2;
private final Context mContext;
private final List<TransactionResultEntity> mTransactionList;
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_HEADER:
View headerView = LayoutInflater.from(mContext)
.inflate(R.layout.row_transaction_header, parent, false);
return new ParentTypeDataObjectHolder(headerView);
case TYPE_CHILD:
View childView = LayoutInflater.from(mContext)
.inflate(R.layout.row_transaction_child, parent, false);
return new ChildTypeDataObjectHolder(childView);
}
return null;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case TYPE_HEADER:
ParentTypeDataObjectHolder parentTypeDataObjectHolder = (ParentTypeDataObjectHolder) holder;
parentTypeDataObjectHolder.headerYearMonthTv.setText(mTransactionList.get(holder.getAdapterPosition()).getRowLabel());
break;
case TYPE_CHILD:
ChildTypeDataObjectHolder childTypeDataObjectHolder = (ChildTypeDataObjectHolder) holder;
childTypeDataObjectHolder.txnAmountTv.setText(mTransactionList.get(holder.getAdapterPosition()).getTransactionAmount());
break;
}
}
#Override
public int getItemCount() {
return mTransactionList.size();
}
#Override
public int getItemViewType(int position) {
if (mTransactionList.get(position).getDataType() == TYPE_HEADER)
return TYPE_HEADER;
else
return TYPE_CHILD;
}
class ParentTypeDataObjectHolder extends RecyclerView.ViewHolder {
private final TextView headerYearMonthTv;
public ParentTypeDataObjectHolder(View itemView) {
super(itemView);
headerYearMonthTv = (TextView) itemView.findViewById(R.id.row_transaction_header_tv);
}
}
class ChildTypeDataObjectHolder extends RecyclerView.ViewHolder {
TextView txnAmountTv;
public ChildTypeDataObjectHolder(View itemView) {
super(itemView);
txnAmountTv = (TextView) itemView.findViewById(R.id.transaction_child_txn_amount_tv);
}
}
}
All you need to do is override the method getItemViewType() inside your adapter.
You can write it as:
#Override
public int getItemViewType(int position) {
if (position < 0) {
return 0;
} else if(position < 20) {
return 1;
} else {
return 2;
}
}
Now the above logic works if your itemsList ArrayList have first 10 items of section 1, next 10 items of section 2, and last 10 items of section 3.
If that is not the case then you can have an integer field sectionNumber in your SingleItemModel class which specifies the section number in which that model belongs to. Now you can modify the method getItemViewType() as
#Override
public int getItemViewType(int position) {
SingleItemModel singleItemModel = itemsList.get(position);
if (singleItemModel.getSection() == 1) {
return 0;
} else if(singleItemModel.getSection() == 2) {
return 1;
} else {
return 2;
}
}
Okay, If I got it right, you want to make the second adapter, the one providing the row lists, variable, so it supports different layouts, based not on its position, but on some data from the main adapter (the one providing the sections). Therefore, overriding getItemViewType won't work, because the section data is contained in the main adapter, it does not even get there. So, the best, and cleanest course, would be to use... abstraction. Forget about multiple viewholders. Use one, and into it, bind a custom view. The custom views will provide both the specific layout files and will set the controls included in them. The holder will do just what it is intended to do: save ram by reusing views. the adavantage of this, is that you can have a clean hierarchy, which can grow in complexity in time, instead of a big, fat adapter which will become too hard to maintain.Here it is:
Since this is a lot of code to put it in here, I took your example project and modified to provide what I understood you were trying to do. Here it is:
https://github.com/fcopardo/exampleCustomViewsInHolder/tree/master
The highlights:
public class SectionListDataAdapter extends RecyclerView.Adapter<SectionListDataAdapter.SingleItemRowHolder> {
private ArrayList<SingleItemModel> itemsList;
private Context context;
private String section;
public SectionListDataAdapter(Context context, ArrayList<SingleItemModel> itemsList, String sectionName) {
this.itemsList = itemsList;
this.context = context;
this.section = sectionName;
}
#Override
public SingleItemRowHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
return new SingleItemRowHolder(RowFactory.getRow(context, section));
}
#Override
public void onBindViewHolder(SingleItemRowHolder holder, int i) {
holder.setData(itemsList.get(i));
}
#Override
public int getItemCount() {
return (null != itemsList ? itemsList.size() : 0);
}
public class SingleItemRowHolder extends RecyclerView.ViewHolder {
protected AbstractRowElement rowElement;
public SingleItemRowHolder(AbstractRowElement view) {
super(view);
this.rowElement = view;
}
public void setData(SingleItemModel singleItemModel){
rowElement.setItem(singleItemModel);
}
}
}
this is the variable layout adapter. As you can see, it uses only one ViewHolder, and a factory to provide the view instances you need.
public class RowFactory {
public static AbstractRowElement getRow(Context context, String name){
switch (name){
case "Section 1": return new FullRowElement(context);
case "Section 2": return new TextRowElement(context);
case "Section 3": return new ImageRowElement(context);
default:
Log.e("inflate", name);
return new FullRowElement(context);
}
}
}
this provides the custom views, each one using a different layout, but working with the same dataset, based on the section title.
public abstract class AbstractRowElement extends CardView{
protected int layout = 0;
protected SingleItemModel singleItemModel;
public AbstractRowElement(Context context) {
super(context);
inflateBaseLayout();
}
public AbstractRowElement(Context context, AttributeSet attrs) {
super(context, attrs);
inflateBaseLayout();
}
public AbstractRowElement(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
inflateBaseLayout();
}
protected void inflateBaseLayout() {
this.setContainer();
if(this.layout != 0) {
LayoutInflater inflater = (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(layout, this, true);
this.inflateComponents();
}
}
protected abstract void setContainer();
protected abstract void inflateComponents();
public void setItem(SingleItemModel itemModel){
this.singleItemModel = itemModel;
this.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getContext(), singleItemModel.getName()+"\n"+singleItemModel.getDescription(), Toast.LENGTH_SHORT).show();
}
});
setData(singleItemModel);
}
public abstract void setData(SingleItemModel itemModel);
}
Finally, this is the base view class for the adapter. Subclasses define the layout file to use, and put the desired data in the controls. The rest is pretty straightforward.
It would be totally possible to make this without custom views. You could just make something like :
int layoutFile = getLayoutForSection(section);
View v = LayoutInflater.from(viewGroup.getContext()).inflate(layoutFile, null);
But since I don't know how complex is the view you intend to create, it is best to keep things nicely separated. Have fun!
Unable to add second child in Recyclerview I am passing two different arrays to RecyclerAdapter to display two child layout with different data and views.Is there any solution to add different child layout using same header layout.I added horizontal Recyclerview in vertical Recyclerview and I want to display details like I attached the image
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
RecyclerAdapter recyclerAdapter = new RecyclerAdapter();
int[] images = new int[]{
R.drawable.finance,
R.drawable.business,
R.drawable.financejob,
R.drawable.ecomchallenges
};
ArrayList<ChildView> childViews = new ArrayList<>();
childViews.add(new ChildView(images[0], "The \"Best\" Startup Pitch Deck - How To Raise Venture Capital", "$100"));
childViews.add(new ChildView(images[1], "An Entire MBA in 1 Course:Award Winning Business School Prof", "$100"));
childViews.add(new ChildView(images[2], "What Finance Job is for You? Explanation of 14 Finance Roles", "$100"));
childViews.add(new ChildView(images[3], "Learn To Build Beautiful HTML5 And CSS3 Websites In 1 Month", "$100"));
int[] courseImage = new int[] {
R.drawable.php,
R.drawable.development,
R.drawable.web,
R.drawable.java
};
ArrayList<CourseByType> courseByTypes = new ArrayList<>();
courseByTypes.add(new CourseByType("Technology", courseImage[0]));
courseByTypes.add(new CourseByType("Business", courseImage[1]));
courseByTypes.add(new CourseByType("Photography", courseImage[2]));
courseByTypes.add(new CourseByType("Development", courseImage[3]));
Log.d("","Above adapter");
recyclerAdapter.addItem(new GroupView("Business", childViews));
Log.d("","Below Child");
recyclerAdapter.addCourseByType(new CourseByHeader("Technology", courseByTypes));
Log.d("","Below Course");
recyclerView.setAdapter(recyclerAdapter);
}
This is the main fragment where I set the values to two different
arraylist ArrayList<ChildView> childViews = new ArrayList<>()
and
ArrayList<CourseByType> courseByTypes = new ArrayList<>()
Values of child views are passing properly but CourseByType values are not passing.This is the adapter class for this fragment class.
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
ArrayList<PassValues> containerArrayList;
ArrayList<GroupView> groupViews;
ArrayList<CourseByHeader>courseByHeaders;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
View view = LayoutInflater.from(context).inflate(R.layout.group_title, parent, false);
return new ViewHolder(view);
}
public RecyclerAdapter(){
containerArrayList = new ArrayList<>();
groupViews = new ArrayList<>();
courseByHeaders = new ArrayList<>();
}
public void addContainer(PassValues container){
containerArrayList.add(container);
}
public void addItem(GroupView groupView){
Log.d("","Inside Group method");
groupViews.add(groupView);
}
public void addCourseByType(CourseByHeader courseByHeader){
Log.d("","Inside Course method");
courseByHeaders.add(courseByHeader);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.d("", "Pass Values out of IF" + position);
ChildViewAdapter childViewAdapter = new ChildViewAdapter();
if(position == 0){
GroupView groupView = groupViews.get(position);
holder.title.setText(groupView.getTitle());
Log.d("", "Passing Values" + groupView.getTitle());
holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.recyclerView.getContext(), LinearLayoutManager.HORIZONTAL, false));
holder.recyclerView.setOnFlingListener(null);
childViewAdapter.addChild(groupView.getChildViewList());
holder.recyclerView.setAdapter(childViewAdapter);
}
if (position == 1) {
CourseByHeader courseByHeader = courseByHeaders.get(position);
holder.title.setText(courseByHeader.getTitle());
Log.d("", "Passing Values" + courseByHeader.getTitle());
holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.recyclerView.getContext(), LinearLayoutManager.HORIZONTAL, false));
holder.recyclerView.setOnFlingListener(null);
childViewAdapter.addCourse(courseByHeader.getCourseByTypes());
holder.recyclerView.setAdapter(childViewAdapter);
}
}
#Override
public int getItemCount() {
if(getItemViewType(0) == TYPE_HEADER)
return groupViews.size() ;
if (getItemViewType(1) == TYPE_ITEM)
return courseByHeaders.size();
else return -1;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
RecyclerView recyclerView;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView)itemView.findViewById(R.id.course_title);
recyclerView = (RecyclerView)itemView.findViewById(R.id.group_recycler);
}
}
}
This RecyclerAdapter contains one RecyclerView in that first row has one image and 3 textviews and 2nd row has 1 ImageView and 1 TextView. At position first,one image and 3 textviews are shown but it's not going on 2nd view
This is the view I getting after run on emulator.
This are two child for RecyclerViews
ChildView.java
public class ChildView {
int image;
String course, price;
public ChildView(int image, String course, String price) {
this.image = image;
this.course = course;
this.price = price;
}
public int getImage() {
return image;
}
public String getCourse() {
return course;
}
public String getPrice() {
return price;
}
}
CourseByType.java
public class CourseByType {
String courseName;
int courseImage;
public CourseByType(String courseName, int courseImage) {
this.courseName = courseName;
this.courseImage = courseImage;
}
public String getCourseName() {
return courseName;
}
public int getCourseImage() {
return courseImage;
}
}
CourseByHeader.java
public class CourseByHeader {
String title;
ArrayList<CourseByType> courseByTypes;
public CourseByHeader(String title, ArrayList<CourseByType> courseByTypes) {
this.title = title;
this.courseByTypes = courseByTypes;
}
public String getTitle() {
return title;
}
public ArrayList<CourseByType> getCourseByTypes() {
return courseByTypes;
}
}
GroupView.java
public class GroupView {
String title;
ArrayList<ChildView> childViewList;
String courseBy;
ArrayList<CourseByType> courseByTypes;
public GroupView(String title, ArrayList<ChildView> childViewList) {
this.title = title;
this.childViewList = childViewList;
}
public String getTitle() {
return title;
}
public ArrayList<ChildView> getChildViewList() {
return childViewList;
}
}
Groupview and CouseByType class have title and child list for recycleradapter
ChildViewAdapter.java
public class ChildViewAdapter extends RecyclerView.Adapter {
ArrayList<ChildView> childViewList;
ArrayList<CourseByType> courseByTypes;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(View itemView) {
super(itemView);
}
}
public class GroupHolder extends ViewHolder {
public ImageView iamView;
public TextView course, price;
public GroupHolder(View itemView) {
super(itemView);
iamView = (ImageView) itemView.findViewById(R.id.course_image);
course = (TextView) itemView.findViewById(R.id.course_by);
price = (TextView) itemView.findViewById(R.id.price);
}
}
public void addCourse(ArrayList<CourseByType> courseByType){
courseByTypes = courseByType;
}
public void addChild(ArrayList<ChildView> childView){
childViewList = childView;
}
public class Course extends ViewHolder {
public ImageView courseTypeImage;
public TextView courseType;
public Course(View itemView) {
super(itemView);
courseTypeImage = (ImageView)itemView.findViewById(R.id.course_image);
courseType = (TextView)itemView.findViewById(R.id.course_name_course);
}
}
public ChildViewAdapter() {
childViewList = new ArrayList<>();
courseByTypes = new ArrayList<>();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
RecyclerView.ViewHolder vh = null;
View v;
if(viewType == TYPE_HEADER){
v = LayoutInflater.from(context).inflate(R.layout.recycler_item, parent, false);
return new GroupHolder(v);
}if(viewType == TYPE_ITEM){
v = LayoutInflater.from(context).inflate(R.layout.type_of_courses, parent, false);
return new Course(v);
}
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof GroupHolder){
Log.d("","instance of Group Holder");
ChildView childView = childViewList.get(position);
((GroupHolder)holder).iamView.setImageResource(childView.getImage());
((GroupHolder)holder).course.setText(childView.getCourse());
((GroupHolder)holder).price.setText(childView.getPrice());
return;
}
if(holder instanceof Course){
Log.d("","instance of Course ");
CourseByType courseByType = courseByTypes.get(position);
((Course)holder).courseTypeImage.setImageResource(courseByType.getCourseImage());
((Course)holder).courseType.setText(courseByType.getCourseName());
return;
}
}
#Override
public int getItemCount() {
int size;
if(childViewList.size()>0){
return size = childViewList.size();
}else return size = courseByTypes.size();
}
#Override
public int getItemViewType(int position) {
if(childViewList.size() != 0 && childViewList.size()>0){
return TYPE_HEADER;
}else return TYPE_ITEM;
}
}
This childview adapter has two view types first is one image and 3 text and second view type contain one image and one text.When I pass values from fragment only first view type get displayed and second view type not gets value from fragment.
To show multiple different views in a recyclerview, you have to override getItemViewType() in the recyclerview adapter.
//getItemViewType enables dynamic viewholder creation
#Override
public int getItemViewType(int position) {
//you will need to add a integer with variable name viewTypeCode
//for view1 set viewTypeCode = 100 and for view2 set viewTypeCode = 200
viewTypeCode = itemList.get(position).getViewTypeCode();
return viewTypeCode;
}
This is how the onCreateViewHolder will be different for multiple viewtypes. You will have to modify yours like this
#Override
public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 100: return new FeedViewHolder(layoutInflater.inflate(R.layout.v1, parent, false),100);
case 200: return new FeedViewHolder(layoutInflater.inflate(R.layout.v2, parent, false),200);
}
return null;
}
OnBindViewHolder will be similarly modified
#Override
public void onBindViewHolder(final FeedViewHolder holder, int position) {
viewTypeCode = itemList.get(position).getViewTypeCode();
switch ( viewTypeCode) {
case 100:
//your code for v1
case 200:
//your code for v2
}
}
Similarly the ViewHolder class is modified
class FeedViewHolder extends RecyclerView.ViewHolder{
//declare variables here
public FeedViewHolder(View v, int viewType) {
super(v);
switch (viewType) {
//instead of itemView.findViewById you will have to use v.findViewById
case 100:
//your code for v1
case 200:
//your code for v2
}
}
For further reference refer to this SO answer
Don't pass two separate list.Make a custom class like this-
class MyClass {
int viewTypeCode;
CustomClass1 c1;
CustomClass2 c2;
//add the setter getter
}
In your activity while preparing the data.
List<MyClass> itemList = new ArrayList<>();
//put whatever logic you need to make the order of the list
//if CustomClass1 object is put then setViewTypeCode(100), setCustomClass2 = null
//if CustomClass2 object is put then setViewTypeCode(200), setCustomClass1 = null
After data is built, then send this to the adapter.
I need to do this: a RecycleView with CardView. The first card is static: it show "Details for this order". The other cards after the first are dynamics. So I decided to do this code:
public class DocumentTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
private List<DocumentType> document; //lista di card da riempire
private Context context;
public DocumentTypeAdapter(List<DocumentType>document, Context context)
{
this.document = document;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view;
if(viewType == 0)
{
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_info, parent, false);
ViewSimple simpleView = new ViewSimple(view);
return simpleView;
}
else
{
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_info, parent, false);
DocumentTypeViewHolder documentTypeViewHolder = new DocumentTypeViewHolder(view);
return documentTypeViewHolder;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
DocumentType documents = document.get(position);
if(getItemViewType(position)!=0)
{
holder.title.setText(documents.getTitle());
holder.cert.setText(documents.getTypeofCertificate());
holder.lastmod.setText(documents.getLastModified());
}
}
#Override
public int getItemCount()
{
return document.size();
}
#Override
public int getItemViewType(int position)
{
return document.size();
}
private class ViewSimple extends RecyclerView.ViewHolder
{
public ViewSimple(View itemView)
{
super(itemView);
}
}
public class DocumentTypeViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
{
TextView title, lastmod,cert;
public DocumentTypeViewHolder(View itemView)
{
super(itemView);
title = (TextView)itemView.findViewById(R.id.tipo);
lastmod = (TextView)itemView.findViewById(R.id.ultimamodifica);
cert = (TextView)itemView.findViewById(R.id.certificato);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
}
}
}
but it doesn't work.
My question are:
how to make the first card static and other dynamics?
my data are in document list. So how to say to method getItemViewType() that the first card is static and others are generated from the size of the list document?
Edit: this is the code with changes:
public class DocumentTypeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
private static final int STATIC_CARD = 0;
private static final int DYNAMIC_CARD = 1;
private List<DocumentType> document;
private Context context;
public DocumentTypeAdapter(List<DocumentType>document, Context context)
{
this.document = document;
this.context = context;
}
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view;
if(viewType == STATIC_CARD)
{
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_info, parent, false);
ViewSimple simpleView = new ViewSimple(view);
return simpleView;
}
else
{
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.document_card_type, parent, false);
DocumentTypeViewHolder documentTypeViewHolder = new DocumentTypeViewHolder(view);
return documentTypeViewHolder;
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
DocumentType documents = document.get(position);
if(getItemViewType(position)==DYNAMIC_CARD)
{
DocumentTypeViewHolder mHolder = (DocumentTypeViewHolder)holder;
mHolder.data.setText(documents.getData());
mHolder.status.setText(documents.getStatus());
Picasso.with(context).load(documents.getImage().toString()).into(mHolder.image, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
Log.d("Picasso","success");
}
#Override
public void onError()
{
Log.d("Picasso","error");
}
});
}
}
#Override
public int getItemCount()
{
return document.size();
}
#Override
public int getItemViewType(int position)
{
if(position == 0)
return STATIC_CARD;
else
return DYNAMIC_CARD;
}
private class ViewSimple extends RecyclerView.ViewHolder
{
public ViewSimple(View itemView)
{
super(itemView);
}
}
public class DocumentTypeViewHolder extends RecyclerView.ViewHolder
{
TextView data, status;
ImageView image;
public DocumentTypeViewHolder(View itemView)
{
super(itemView);
data = (TextView)itemView.findViewById(R.id.dateCharging);
status =(TextView)itemView.findViewById(R.id.statusCharging);
image = (ImageView)itemView.findViewById(R.id.documentImage);
}
}
}
Thanks for your answers
You should override getItemViewType() and make it return a different value when it should be a dynamic card or when its a static card. Since you want the first card to be static you should return a different value when position == 0. This will look something like this:
private static final int STATIC_CARD = 0;
private static final int DYNAMIC_CARD = 1;
#Override
public int getItemViewType(int position) {
if(position == 0) {
return STATIC_CARD;
} else {
return DYNAMIC_CARD;
}
}
Then in your onCreateViewHolder() method you should check the viewType and based on the outcome you should inflate a View, which you were already doing OK, but I would replace the hardcoded 0 with the private static final int STATIC_CARD.
Edit: Just came to my mind, if you only need one static card, you might want to consider placing a CardView in your Fragment/Activity xml layout and place the rest of the dynamic cards in a RecyclerView below that static card.
I'll suggest you to use a library that already correctly implement/handles all that for you: https://github.com/eyeem/RecyclerViewTools
Full disclosure: I wrote the library
Just write your adapter for the dynamic items and then:
DocumentTypeAdapter adapter = new // your adapter here
WrapAdapter wrapAdapter = new WrapAdapter(adapter); // that's from the library
wrapAdapter.addHeader( /* add here your static view */ );
recyclerView.setAdapter(wrapAdapter);
and add those to your build.gradle
repositories {
maven {
url 'https://oss.sonatype.org/content/repositories/snapshots/'
}
}
dependencies {
compile 'com.eyeem.recyclerviewtools:library:0.0.3-SNAPSHOT#aar'
}