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.
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 building a sample transaction app with the ability to categorize the list item based on its category. e.g. user can add a new list item with category sport and i would like to have a sport as header in the recyclerview and later on if item with category movie added, then the new item will be under movie.
I understand that i have to provide the itemViewType in my adapter class. and then i will have a List<txn> that mixed with different view types.
my current approach in following block is using Map<String, List<Item>> to keep track of each new item for particular category. But I was told one of my colleague that there is more efficient way to handle this.
But what kind of data structures I should use so that I can support
user can add any new category.
when user use the existing category,
then it should be add into the particular section in the recycler
view only?
public class txnAdapter extends
RecyclerView.Adapter<RecyclerView.ViewHolder> {
public static final int TRANSCATION_TYPE = 1;
public static final int HEAD_TYPE = 2;
private List<Txn> txns;
private List<Object> items;
private Map<String, List<Txn>> map;
public txnAdapter() {
map = new HashMap<>();
txns = new ArrayList<>();
items = new ArrayList<>();
}
public void setTxns(List<Txn> txns) {
//make a copy
this.txns.addAll(txns);
addToMap(txns);
resetList(this.txns);
}
public void addTxn(Txn txn) {
//filter by type and insert.
//find the index of category in list and
List<Txn> list = new ArrayList<>();
list.add(txn);
addToMap(list);
resetList(this.txns);
}
void addToMap(List<Txn> txns){
for(Txn t: txns){
if(!map.containsKey(t.getCategory())){
map.put(t.getCategory(), new ArrayList<Txn>());
}
List<Txn> list = map.get(t.getCategory());
list.add(t);
map.put(t.getCategory(), list);
}
}
void resetList(List<Txn> txns) {
items.clear();
for(Map.Entry<String, List<Txn>> e: map.entrySet()){
if(!items.contains(e.getKey())){
items.add(e.getKey());
}
items.addAll(e.getValue());
}
notifyDataSetChanged();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
//inflat the layout
View itemView = null;
if (viewType == HEAD_TYPE) {
itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_header, parent, false);
return new headerViewHolder(itemView);
} else if (viewType == TRANSCATION_TYPE) {
itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new transcationViewHolder(itemView);
}
return new transcationViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
Object cur = this.items.get(position);
if (holder instanceof headerViewHolder) {
((headerViewHolder) holder).gategoryTV.setText((String) cur);
} else if (holder instanceof transcationViewHolder) {
((transcationViewHolder) holder).titleTV.setText(((Txn) cur).getTitle());
((transcationViewHolder) holder).dateTV.setText(((Txn) cur).getDate());
((transcationViewHolder) holder).amountTV.setText(((Txn) cur).getAmount() + "");
}
}
#Override
public int getItemCount() {
return items == null ? 0 : items.size();
}
#Override
public int getItemViewType(int position) {
if (items.get(position) instanceof String) {
//this is header
return HEAD_TYPE;
} else if (items.get(position) instanceof Txn) {
return TRANSCATION_TYPE;
}
return -1;
}
private class transcationViewHolder extends RecyclerView.ViewHolder {
private TextView titleTV;
private TextView dateTV;
private TextView amountTV;
public transcationViewHolder(#NonNull View itemView) {
super(itemView);
this.titleTV = itemView.findViewById(R.id.title);
this.dateTV = itemView.findViewById(R.id.date);
this.amountTV = itemView.findViewById(R.id.amount);
}
}
private class headerViewHolder extends RecyclerView.ViewHolder {
private TextView gategoryTV;
public headerViewHolder(#NonNull View itemView) {
super(itemView);
this.gategoryTV = itemView.findViewById(R.id.category);
}
}
Try this library I think it should full fill your requirements,
https://github.com/luizgrp/SectionedRecyclerViewAdapter
you have to do some customisation there it surely work.
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;
}
}
}
I have to set just four data from API in Recyclerview. The data from API are dynamic.If there are more than 4 data then the last one should hide itself and the recent data should appear at the top. I have researched but could not find the applicable solution.
My Adpater
public class EventRecyclerAdapter extends RecyclerView.Adapter<EventRecyclerAdapter.MyViewHolder> {
Context context;
private ArrayList<String> start;
private AdapterView.OnItemClickListener listener;
private ArrayList<String> desc;
private ArrayList<EventData>data;
public EventRecyclerAdapter(Context context, ArrayList<EventData> data) {
this.context = context;
this.data = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.content_events, parent, false);
return new EventRecyclerAdapter.MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(EventRecyclerAdapter.MyViewHolder holder, int position) {
holder.start.setText(data.get(position).getStartDate());
holder.des.setText(Html.fromHtml(data.get(position).getName()));
}
#Override
public int getItemCount() {
return data.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView start, des, viewall,name;
private CardView cardView;
public MyViewHolder(View itemView) {
super(itemView);
start = (TextView) itemView.findViewById(R.id.startdate);
des = (TextView) itemView.findViewById(R.id.description);
viewall = (TextView) itemView.findViewById(R.id.viewall);
}
}
}
I have set the data as follows
private void initEventRecycler() {
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
eventR.setLayoutManager(mLayoutManager);
eventR.setItemAnimator(new DefaultItemAnimator());
eventR.setNestedScrollingEnabled(false);
eventRecyclerAdapter = new EventRecyclerAdapter(MainActivity.this, events);
eventR.setAdapter(eventRecyclerAdapter);
}
If you have shorted data in the array list you are getting in adapter then use this code to show only 5 items.
#Override
public int getItemCount() {
if (data!= null && data.size() < 5) {
return data.size();
} else {
return 5;
}
}
if you have a data list in random order then first short it from latest to old and send to adapter.
Hope it will work for you.
EventData[] mData = new EventData[4];
int writeIndex = 0;
public void add(Object o) {
ring[writeIndex % ring.length] = o;
writeIndex++;
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mData.lenght;
}
You can also Check ArrayCircularQueue.java
Card 1 for Ingredients and layout 2 for steps - Image public class DetailAdapter extends RecyclerView.Adapter {
private List<Ingredient> ingredientList;
private List<Step> stepList;
private Context context;
private boolean check;
private int which_layout;
public DetailAdapter(Context context, BakingModel bakingModel){
// Log.d("Inside Adapter" , bakingModel.getIngredients().get(0).getIngredient());
this.context = context;
ingredientList = bakingModel.getIngredients();
ingredientList.addAll(bakingModel.getIngredients());
stepList = bakingModel.getSteps();
stepList.addAll(bakingModel.getSteps());
Log.d("Inside Adapter" , ingredientList.get(0).getIngredient());
check = false;
which_layout = 0;
}
public static class DetailView1 extends RecyclerView.ViewHolder {
#Nullable#BindView(R.id.ingredient)
TextView textView_ing;
#Nullable#BindView(R.id.ingredient_list)
EditText editText_inglist;
public DetailView1(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
public static class DetailView2 extends RecyclerView.ViewHolder{
#Nullable #BindView(R.id.step)
TextView textView_step;
public DetailView2(View itemView) {
super(itemView);
ButterKnife.bind(this,itemView);
}
}
#Override
public int getItemViewType(int position) {
if(!check){
which_layout = 1;
check = true;
Log.d("getItemView","Layout 1");
}
else {
which_layout = 2;
}
return which_layout;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
switch (which_layout){
case 1 :
View v1 = inflater.inflate(R.layout.fragment_detail1,viewGroup,false);
viewHolder = new DetailView1(v1);
Log.d("onCreateView","Create Layout 1");
break;
default:
View v2 = inflater.inflate(R.layout.fragment_detail2,viewGroup,false);
viewHolder = new DetailView2(v2);
Log.d("onCreateView","Create Layout 2");
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int i) {
switch (viewHolder.getItemViewType()) {
case 1 :
DetailView1 detailView1 = (DetailView1) viewHolder;
detailView1.textView_ing.setText(R.string.ingredients);
for(Ingredient ingredient : ingredientList) {
detailView1.editText_inglist.append(ingredient.getIngredient() + "\n");
}
Log.d("onBindView","Bind Layout 1");
break;
default:
DetailView2 detailView2= (DetailView2) viewHolder;
detailView2.textView_step.setText(stepList.get(i).getShortDescription());
Log.d("onBindView","Bind Layout 2");
}
}
#Override
public int getItemCount() {
return stepList.size()+1;
}
}
When I change the value of which layout under the getItemView to 1 then the same edit text is filled stepList.size() number of times. Otherwise if it is as it is now, then there is no edit text. Only the step description that is DetailView2 is being populated.
DetailView1 is being replaced by DetailView2.
Edit : Basically what I am trying to achieve is create a card for ingredients. And then multiple cards for steps.