I happened to run into one little problem. In my project I use DataBinding and RecyclerView to bind data to ViewHolders and display it. Problem is: on first bind TextView width is much larger than text in it (layout_widthis set to wrap_content).
Here is my XML code.
<LinearLayout
android:id="#+id/messageBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="0.7"
android:gravity="center_vertical"
android:paddingLeft='#{same?#dimen/four:#dimen/zero}'
android:paddingRight='#{(mess.isMine && same)?#dimen/four:#dimen/zero}'
android:text='#{mess.message,default = "Message"}'
android:textAppearance="#style/Base.TextAppearance.AppCompat.Medium"
android:textColor="#color/black"
android:textSize="14sp" />
<android.support.v7.widget.AppCompatTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0.35"
android:gravity="bottom|end"
android:layout_gravity="bottom|end"
android:lines="1"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:text='#{Utils.parseMillsToHoursAndMins(mess.date,true,true),default = "14:22"}'
android:textAppearance="#style/Base.TextAppearance.AppCompat.Small"
android:textSize="12sp"/>
</LinearLayout>
In onBindViewHoder I simply call holder.binding.setVariable(..), so nothing special.
I attached two images with results. Fist one - first binding. Second one - after scrolling up and down.
Update. Binding code
#Override
public void onBindViewHolder(final BindingViewHolder holder, int position) {
holder.getBinding().setVariable(BR.mess, data.get(holder.getAdapterPosition()));
}
Update 2. onCreateViewHolder() code
#Override
public BindingViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case TYPE_ITEM: {
return new MessageItemViewHolder(DataBindingUtil.inflate(inflater, R.layout.rv_item_message_item, parent, false).getRoot());
}
case TYPE_HEADER: {
return new MessageHeaderViewHolder(DataBindingUtil.inflate(inflater, R.layout.rv_item_message_header, parent, false).getRoot());
}
default:
throw new IllegalStateException("Inaccepteble view type");
}
}
Yea, there is actually 2 view types.
Related
I'm working on a chatting application. All I did is i can get api response successfully and can show them serially like this
This is id of sender and reciver
This is the messages
For doing this I created an adapter which code is something like this.
public class Single_chat_adapter extends RecyclerView.Adapter<Single_chat_adapter.Single_chat_adapterViewHolder>{
private List<Datum2> data;
private int rowLayout;
private Context context;
public Single_chat_adapter(List<Datum2> data, int rowLayout, Context context) {
this.data = data;
this.rowLayout = rowLayout;
this.context = context;
}
#Override
public Single_chat_adapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card2, parent, false);
return new Single_chat_adapterViewHolder(view); }
#Override
public void onBindViewHolder(Single_chat_adapterViewHolder holder, int position) {
holder.single_msg.setText(data.get(position).getMsg());
}
#Override
public int getItemCount() {
return data.size();
}
public class Single_chat_adapterViewHolder extends RecyclerView.ViewHolder {
TextView single_msg;
public Single_chat_adapterViewHolder(View itemView) {
super(itemView);
single_msg =itemView.findViewById(R.id.userNameTV);
}
}
}
Here I use a single view which is card2.xml. But all I need to do is set senders message in the left side and receiver message in other side.
What To do?
To achieve what you have explained, Create two views in card2.xml(one at the left and the other in the right). I have created one for you.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:layout_marginBottom="6dp"
android:layout_marginTop="4dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="40dp"
android:id="#+id/avatar"
android:background="#drawable/circle_stroke"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:src="#drawable/useric"
android:layout_height="40dp" />
<RelativeLayout
android:layout_toEndOf="#+id/avatar"
android:id="#+id/msg_back"
android:layout_marginBottom="5dp"
android:layout_gravity="center_vertical"
android:background="#drawable/message_bubble_accent"
android:layout_width="match_parent"
android:padding="10dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:textSize="17sp"
android:id="#+id/user_text"
android:layout_width="wrap_content"
android:textColor="#color/white"
android:text="Hello world how are you?"
android:layout_height="wrap_content" />
<TextView
android:textSize="12sp"
android:layout_below="#+id/user_text"
android:id="#+id/chat_time"
android:textColor="#color/dark"
android:text="3:33pm"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
<ImageView
android:layout_width="40dp"
android:id="#+id/avatar2"
android:layout_alignParentEnd="true"
android:layout_below="#+id/msg_back"
android:background="#drawable/circle_stroke"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:src="#drawable/useric"
android:layout_height="40dp" />
<RelativeLayout
android:layout_toStartOf="#+id/avatar2"
android:layout_below="#+id/msg_back"
android:id="#+id/msg_back2"
android:layout_gravity="center_vertical"
android:background="#drawable/message_bubble_white"
android:layout_width="match_parent"
android:padding="10dp"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:textSize="17sp"
android:id="#+id/user_text2"
android:layout_width="wrap_content"
android:textColor="#color/white"
android:text="Hello world how are you?"
android:layout_height="wrap_content" />
<TextView
android:layout_below="#+id/user_text2"
android:id="#+id/chat_time2"
android:textColor="#color/dark"
android:text="3:33pm"
android:textSize="12sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_alignParentEnd="true"
android:layout_below="#+id/user_text2"
android:text="#string/sent"
android:width="20dp"
android:textAppearance="?android:textAppearanceSmall"
android:layout_width="20dp"
android:layout_height="20dp"
android:textColor="#android:color/holo_green_light"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
Modify your onBindViewHolder and add the condition that will check if the message is coming from another user or not. Like this...
#Override
public void onBindViewHolder(Single_chat_adapterViewHolder holder, int position) {
Datum2 datum = data.get(position);
holder.single_msg.setText(datum.getMsg());
int msgId = datum.getMsgId();
if (msgId == datum.getUserMsgId) {
//Do everything pertaining to this user here
holder.rightBubble.setText(single_msg);
//holder.rightAvatar.setText(single_msg) //For setting image
} else {
holder.leftBubble.setText(single_msg);
}
}
Make sure you reference leftBubble and rightBubble from you ViewHolder, and set the current userMsgid from the activity that is using this adapter.
You have to create 2 viewtype and two xml for them additionally and load them in a single adapter. Follow the link may help you.
Android Chat Tutorial: Building a Messaging UI
1) Create 2 views in card2.xml
2) One for left and another for right
3) Put condition in your onBindViewHolder, if message is from senders make left view visible and hide right view and same thing for right view also.
You can put condition inside onCreateViewHolder, this will let you to swap the layout (xml file)
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
switch (viewType) {
case Message.TYPE_MESSAGE:
layout = R.layout.item_message;
break;
case Message.TYPE_LOG:
layout = R.layout.item_log;
break;
case Message.TYPE_ACTION:
layout = R.layout.item_action;
break;
}
View v = LayoutInflater
.from(parent.getContext())
.inflate(layout, parent, false);
return new ViewHolder(v);
}
You can change viewtype from this method
#Override
public int getItemViewType(int position) {
// Just as an example, return 0 or 2 depending on position
// Note that unlike in ListView adapters, types don't have to be contiguous
return position % 2 * 2;
}
I need an output like this. That is HorizontalRecyclerView as a header for VerticalRecyclerView.
Currently I'm using NestedScrollView to attain this design. But I felt scrolling is not smooth.
Please suggest any idea. Thanks in advance.
Layout:
<android.support.v4.widget.NestedScrollView
android:id="#+id/nsv_my_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="ifContentScrolls"
android:visibility="gone"
android:clipChildren="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="15dp">
<LinearLayout
android:id="#+id/ll_continue_watching"
android:layout_width="match_parent"
android:layout_height="132dp"
android:visibility="gone"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="29dp"
android:gravity="center_vertical"
android:paddingLeft="15dp"
android:paddingRight="15dp">
<customview.font.TextView
android:id="#+id/txt_edit_remove_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="#drawable/btn_profile_edit"
android:gravity="center"
android:paddingTop="2dp"
android:text="EDIT"
android:textSize="10sp" />
<customview.font.TextView
android:id="#+id/txt_continue_watchng"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:text="Continue watching"
android:textSize="12sp" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#color/horizontal_view_color" />
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_horizontal_view"
android:layout_width="match_parent"
android:layout_height="102dp"
android:paddingBottom="15dp"
android:paddingTop="15dp" />
<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#color/horizontal_view_color" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_vertical_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Very simple, your "main" recycler view has 2 kind of cells, the first one, that is another recycler view, and the rest that are "normal" cells.
On the adapter of your "main" recycler view, you have to Override the method getItemViewType, something like this:
#Override
public int getItemViewType(int position) {
if(postition == 0) {
return 1; //Let's say that you define that 1 is the view type for the recycler view cell
}
else {
return 2; //And 2 is going to be the "normal" cells
}
}
Then, on your onCreateViewHolder method, depending on the view type, you must build and return the correct viewHolder, something like this:
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
if(viewType == 1) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.your_other_recyclerview_layout, parent, false);
//build the viewHolder
ViewHolder vh = new YourOtherRecyclerViewHolder(v);
return vh;
}
else {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.your_normal_cell_layout, parent, false);
//build the normal viewHolder
YourNormalViewHolder vh = new YourNormalViewHolder (v);
return vh;
}
}
Of course you must implement 2 classes that extends the ViewHolder class, one for YourOtherRecyclerViewHolder, and the other one for YourNormalViewHolder.
I hope it helps!
I have 2 problems with my current recycler view with cardview. The first is with the checkbox. The checkboxs seem to check/uncheck themselves all the time. I know I need to set onCheckedChangeListener, just not sure what to put in it. My second issue is each item in the recycler view/cardview has 4 Strings and 1 checkbox, but sometimes one of the strings is too large, which screws up the whole thing.. Is there any way if a string is too long I can make it make the cardview larger so one of the words will go underneath the first word?
Here is the custom object class:
public class Workout{
private String exercise;
private String percent;
private String reps;
private String weight;
private boolean check1;
public Workout(String exercise, String percent, String reps, String weight, boolean check1) {
this.exercise = exercise;
this.percent = percent;
this.reps = reps;
this.weight = weight;
this.check1 = check1;
}
/* accessors omitted for readability */
}
Here is the adapter:
public class MyRecyclerAdapter extends RecyclerView.Adapter<MyViewHolder> {
Context mContext;
ArrayList<Workout> workout;
public MyRecyclerAdapter(Context context, ArrayList<Workout> workout) {
mContext = context;
this.workout = workout;
}
// INITIALIZE HOLDER
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.workout_item, null);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
//BIND DATA TO VIEWS
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final Workout objWorkout = workout.get(position);
holder.exercise.setText(workout.get(position).getExercise());
holder.percent.setText(workout.get(position).getPercent());
holder.reps.setText(workout.get(position).getReps());
holder.weight.setText(workout.get(position).getWeight());
holder.check1.setOnCheckedChangeListener();
//LISTENER
holder.setItemClickListener(new ItemClickListener() {
#Override
public void onItemClick(View view, int pos) {
Toast.makeText(mContext, workout.get(pos).getExercise(),Toast.LENGTH_LONG).show();
}
});
}
#Override
public int getItemCount() {
return workout.size();
}
}
Here is the xml for custom item:
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_width="wrap_content"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_margin="10dp"
card_view:cardCornerRadius="10dp"
card_view:cardElevation="10dp" >
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="15dp"
android:paddingLeft="15dp"
android:paddingRight="15dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Squat"
android:textSize="20sp"
android:id="#+id/txtExercise"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="%"
android:textSize="20sp"
android:id="#+id/txtPercentage"
android:paddingLeft="30dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/txtExercise"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Reps"
android:textSize="20sp"
android:id="#+id/txtReps"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Weight"
android:textSize="20sp"
android:id="#+id/txtWeight"
android:layout_alignParentTop="true"
android:layout_toLeftOf="#+id/check1"
android:layout_toStartOf="#+id/check1"/>
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/check1"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="31dp"
android:layout_marginEnd="31dp"
android:checked="false"/>
</RelativeLayout>
Thanks for the help!
For your check box issue:
You need to call holder.check1.setChecked(boolean) in the onBind. Keep in mind that onBind is called several times for each view. So when you scroll, and the recycler view is recycling, it is reusing a checkbox that you aren't specifying if they are checked or not.
Also, because onBind is call so frequently it is best to not set the listener there. Set the listener in the constructor of the view holder.
EDIT
In your listener store the value if it is checked or not. This is usually stored in the object that you are displaying, in your case workout. If you don't have a value there for that, you can use SparseBooleanArray. It is really good for keeping track of what is checked and not.
For your text issue:
sometimes one of the strings is too large, which screws up the whole thing
I am not too sure what you mean. But looking at your xml you do a lot things as far as layout_alignParentTop or layout_toLeftOf. I bet it is something wrong with those once one text is too large. Try changing your root layout to a LinearLayout or try to remove as many of those rules as you can. I bet you will discover your bug when doing that.
I am getting something weird while implementing a RecyclerView which I can't understand.
I am using a button with default style, which uses colorAccent from values/colors.xml
<Button
android:id="#+id/next_button"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:enabled="true"
android:text="Next" />
When I use this button statically in layout XML I get the expected button color i.e. -
But when I inflate the button in RecyclerView I get an unexpected color, which I haven't defined anywhere in the app -
(The Button I am adding is the last element of the RecyclerView as explained here - How to create RecyclerView with multiple view type?
The code to inflate the view -
//ListAdapter constructer
public ListAdapter(Context context, List<postDetail> dataList1) {
this.context = context;
this.dataList = dataList1;
inflater = LayoutInflater.from(context);
}
public ListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View convertView;
if(viewType == 0){
convertView = inflater.inflate(R.layout.home_individual_post, parent, false);
ListViewHolder viewHolder = new ListViewHolder(convertView,0);
return viewHolder;
} else {
convertView = inflater.inflate(R.layout.prev_next,parent,false);
ListViewHolder viewHolder = new ListViewHolder(convertView,1);
return viewHolder;
}
}
//The button is in prev_next.xml
prev_next.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="#+id/next_prev_button"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="50dp"
android:gravity="center_vertical"
>
<Button
android:id="#+id/prev_button"
style="#style/MyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="-4dp"
android:enabled="true"
android:textColor="#FFF"
android:text="Previous"
/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<Button
android:id="#+id/next_button"
style="#style/MyButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="-4dp"
android:textColor="#FFF"
android:enabled="true"
android:text="Next" />
</LinearLayout>
The background color issue is in both layout - prev_next.xml and home_individual_post.xml
I found the problem and has mentioned the same in an answer below
I found the problem, not sure about the reason. But the solution works.
While creating the adapter I was doing -
adapter = new ListAdapter(getApplicationContext(), Posts);
and then the theme issue was there, but when i changed getApplicationContext() to getBaseContext(), it worked -
adapter = new ListAdapter(getBaseContext(), Posts);
The problem appears to be that I was creating the adapter from a asynchronous thread
Can you please try to change your inflation code like
LayoutInflater.from(getContext()).inflate(R.layout.yourcell, parent/container, false);
I'm displaying daily events. The number of events/day is variable. Each item in the RecView is a Day which should contain as many views as the number of events.
Here is one item's layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/llDay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDay"
android:text="TODAY"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvNothing"
android:text="No events"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textStyle="italic"
android:visibility="gone"/>
</LinearLayout>
I'd like to add views to the llDay dynamically.
Here is my Adapter:
public class DiaryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
ArrayList<ArrayList<Displayable>> diaryEvents = new ArrayList<>();
Context context;
public DiaryAdapter(ArrayList<ArrayList<Displayable>> diaryEvents, Context context) {
this.diaryEvents = diaryEvents;
this.context = context;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewGroup viewGroup = (ViewGroup) LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_day_diary, parent, false);
DiaryDayViewHolder viewHolder = new DiaryDayViewHolder(viewGroup);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
DiaryDayViewHolder viewHolder = (DiaryDayViewHolder) holder;
ArrayList<Displayable> events = diaryEvents.get(position);
if (events.size() > 0){
addLayouts(events, viewHolder);
}
else{
viewHolder.tvNothing.setVisibility(View.VISIBLE);
}
}
#Override
public int getItemCount() {
return diaryEvents.size();
}
private void addLayouts(ArrayList<Displayable> events, DiaryDayViewHolder viewHolder) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
for (Displayable event : events) {
switch (event.getEventType()){
case Types.TYPE_TEACHING:
TeachingDiaryLayout teachingDiaryLayout = new TeachingDiaryLayout(context);
teachingDiaryLayout.setLayoutParams(params);
teachingDiaryLayout.setViews((Teaching) event);
viewHolder.llDay.addView(teachingDiaryLayout);
viewHolder.tvDay.setText("DAY"); // TODO: day + date
break;
case Types.TYPE_TASK: // TODO
break;
case Types.TYPE_EXAM: // TODO
break;
}
}
}
}
When the RecyclerView is displayed first, the events are displayed correctly, but after scrolling some events are displayed multiple times. I know that the problem is caussed by calling the addLayouts(...) in the onBindViewHolder(...) but I don't know how to create the correct amount of views for each day.
UPDATE: ViewHolder added:
public static class DiaryDayViewHolder extends RecyclerView.ViewHolder {
LinearLayout llDay;
TextView tvDay;
TextView tvNothing;
public DiaryDayViewHolder(View itemView) {
super(itemView);
llDay = (LinearLayout) itemView.findViewById(R.id.llDay);
tvDay = (TextView) itemView.findViewById(R.id.tvDay);
tvNothing = (TextView) itemView.findViewById(R.id.tvNothing);
}
}
Ok finally figured it out.
Firstly change your layout to:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/llDay">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvDay"
android:text="TODAY"
android:layout_gravity="center_horizontal"
android:layout_marginTop="15dp"
android:textSize="25sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/tvNothing"
android:text="No events"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:textSize="18sp"
android:textStyle="italic"
android:visibility="gone"/>
<LinearLayout
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/llDay1"/>
</LinearLayout>
now in your view holder add another LinearLayout parameter:
LinearLayout llDay,llday1;
and inside the addLayouts method change:
viewHolder.llDay.addView(teachingDiaryLayout);
to
viewHolder.llDay1.addView(teachingDiaryLayout);
Also before the for loop add
viewHolder.llDay1.removeAllViews();
for (Displayable event : events)