I cannot sort the RecyclerView in descending order by date. There are headers and items. I can only sort items, but no headers.
I tried to sort the SQL Database in descending order (" DESC"), but not successful.
private static final String EVENTS_CREATE_TABLE =
"create table "
+ EVENTS.TABLE + " ("
+ EVENTS.EVENTS_ID + " integer primary key, "
+ EVENTS.COL_TITLE + " text, "
+ EVENTS.COL_DATE + " long" + ");";
``
public List<EventModel> getAllEvents() {
List<EventModel> eventModelList = new ArrayList<>();
openToRead();
String orderBy = DBHelper.EVENTS.COL_DATE + " DESC";
Cursor cursor = database.query(DBHelper.EVENTS.TABLE,
null, null, null, null, null, orderBy);
if (cursor.moveToFirst()) {
do {
String title = cursor.getString(cursor.getColumnIndex(DBHelper.EVENTS.COL_TITLE));
long date = cursor.getLong(cursor.getColumnIndex(DBHelper.EVENTS.COL_DATE));
EventModel eventModel = new EventModel(title, date);
eventModelList.add(eventModel);
} while (cursor.moveToNext());
}
cursor.close();
return eventModelList;
}
There is my fragment:
private void getList() {
List<ListEvent> items = new ArrayList<>();
Map<Long, List<EventModel>> events = toMap(loadEvents());
for (long date : events.keySet()) {
HeaderEvent header = new HeaderEvent(date);
items.add(header);
for (EventModel eventModel : events.get(date)) {
EventItem item = new EventItem(itemModel);
items.add(item);
}
}
adapterEvent = new EventRVAdapter(getContext(), items);
mRecyclerView.setAdapter(adapterEvent);
}
private List<EventModel> loadEvents() {
List<EventModel> events = new ArrayList<>(mDBAdapter.getAllEvents());
return events;
}
private Map<Long, List<EventModel>> toMap(List<EventModel> events) {
Map<Long, List<EventModel>> map = new TreeMap<>();
for (EventModel eventModel : events) {
List<EventModel> value = map.get(eventModel.getDate());
if (value == null) {
value = new ArrayList<>();
map.put(eventModel.getDate(), value);
}
value.add(eventModel);
}
return map;
}
This is ListEvent class:
public abstract class ListEvent {
public static final int TYPE_HEADER = 0;
public static final int TYPE_ITEM = 1;
abstract public int getType();
}
This is EventItem.class
public class EventItem extends ListEvent{
private EventModel eventModel;
public EventItem(EventModel eventModel) {
this.eventModel = eventModel;
}
public EventModel getEventModel() {
return eventModel;
}
#Override
public int getType() {
return TYPE_ITEM;
}
}
This is HeaderEvent class:
public class HeaderEvent extends ListEvent {
private long date;
public HeaderEvent(long date) {
this.date = date;
}
public long getDate() {
return date;
}
#Override
public int getType() {
return TYPE_HEADER;
}
}
This is my Model - EventModel class:
public class EventModel {
private String title;
private long date;
public EventModel(String title, long date) {
this.title = title;
this.date = date;
}
public String getTitle(){
return title;
}
public long getDate(){
return date;
}
}
And my RecyclerView adapter:
public class EventRVAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ListEvent> items;
public EventRVAdapter(List<ListEvent> items) {
this.items = items;
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView tvName, tvDate;
public ItemViewHolder(#NonNull View itemView) {
super(itemView);
tvName = itemView.findViewById(R.id.tvTitle);
tvDate = itemView.findViewById(R.id.tvDate);
}
}
public class HeaderViewHolder extends RecyclerView.ViewHolder {
private TextView tvHeaderDate;
public HeaderViewHolder(#NonNull View itemView) {
super(itemView);
tvHeaderDate = itemView.findViewById(R.id.tvHeader);
}
}
#Override
public int getItemCount() {
return items.size();
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ListEvent.TYPE_HEADER: {
View itemView = inflater.inflate(R.layout.row_header, parent, false);
return new HeaderViewHolder(itemView);
}
case ListEvent.TYPE_ITEM: {
View itemView = inflater.inflate(R.layout.row_item, parent, false);
return new ItemViewHolder(itemView);
}
default:
throw new IllegalStateException("unsupported item type");
}
}
#Override
public void onBindViewHolder(#NonNull RecyclerView.ViewHolder holder, int position) {
int viewType = getItemViewType(position);
switch (viewType) {
case ListEvent.TYPE_HEADER: {
HeaderEvent header = (HeaderEvent) items.get(position);
HeaderViewHolder headerHolder = (HeaderViewHolder) holder;
headerHolder.tvHeaderDate.setText(Utils.getDayAndTime(header.getDate()));
break;
}
case ListEvent.TYPE_ITEM: {
EventItem event = (EventItem) items.get(position);
ItemViewHolder itemHolder = (ItemViewHolder) holder;
itemHolder.tvName.setText(event.getEventModel().getTitle());
itemHolder.tvDate.setText(Utils.getDateWithoutTime(event.getEventModel().getDate()));
break;
}
default:
throw new IllegalStateException("unsupported item type");
}
}
#Override
public int getItemViewType(int position) {
return items.get(position).getType();
}
}
Could you help me to find solution or give advice?
keySet() method documentation claims:
The set's iterator returns the keys in ascending order.
And this is just the behaviour you have.
There is no need to use Map to prepare list of items with headers. It's better to just iterate the sorted list of events and store last date to compare to at the next step. Here is a code sample:
List<EventModel> events = loadEvents();
List<ListEvent> items = new ArrayList<>();
long date = -1L;
for (EventModel event : events) {
if (event.getDate() != date) {
date = event.getDate();
items.add(new HeaderEvent(date));
}
items.add(new EventItem(event));
}
and thank you for your attention to my request.
I'm a newbie on Andorid Studio and I'm developing an App, it has to show a list of Events, Courses and News. There is a DrawerLayout which allow navigating into Event's, course's and news's area, each area has each specific RecyclerView, but into the home activity, I have to show all the items (Event, Course and News).
I create an Adapter for each item (because they have different properties) and each section (fragment) works properly but now I'm stuck with the main activity (the home).
Here are the models for explaining the difference between them:
Event
public class Event {
private int id;
private String title;
private String description;
private LocalDateTime startingDate;
private LocalDateTime endingDate;
private String cost;
private String website;
private Category category;
private Venue venue;
private Organizer organizer;
private String status;
private int resImage;
public Event(int id, String title, String description, LocalDateTime startingDate, LocalDateTime endingDate, String cost, String website, Category category, Venue venue, Organizer organizer, int image) {
this.id = id;
this.title = title;
this.description = description;
this.startingDate = startingDate;
this.endingDate = endingDate;
this.cost = cost;
this.website = website;
this.category = category;
this.venue = venue;
this.organizer = organizer;
this.resImage = image;
}
public Event(){}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String name) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public LocalDateTime getStartingDate() {
return startingDate;
}
public void setStartingDate(LocalDateTime startingDate) {
this.startingDate = startingDate;
}
public LocalDateTime getEndingDate() {
return endingDate;
}
public void setEndingDate(LocalDateTime endingDate) {
this.endingDate = endingDate;
}
public String getCost() {
return cost;
}
public void setCost(String cost) {
this.cost = cost;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public Category getCategory() {
return category;
}
public Venue getVenue() {
return venue;
}
public Organizer getOrganizer() {
return organizer;
}
public String getStatus() {
return status;
}
public int getResImage() {
return resImage;
}
}
News:
public class News {
private int id;
private String title;
private String content;
private int resImage;
public News(int id, String title, String content, int image) {
this.id = id;
this.title = title;
this.content = content;
this.resImage = image;
}
public News(){}
public int getId(){
return this.id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setDescription(String description) {
this.content = content;
}
public int getResImage() {
return resImage;
}
public void setResImage(int resImage) {
this.resImage = resImage;
}
}
Courses
public Course(int id, String title, String content, float price, LocalDate startingDate, int availablePlace, Teacher teacher, CourseCategory courseCategory, Location location, Duration duration, Level level, int resImage) {
this.id = id;
this.title = title;
this.content = content;
this.price = price;
this.startingDate = startingDate;
this.availablePlace = availablePlace;
this.teacher = teacher;
this.courseCategory = courseCategory;
this.location = location;
this.duration = duration;
this.level = level;
this.resImage = resImage;
}
public int getId() {
return id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public LocalDate getStartingDate() {
return startingDate;
}
public void setStartingDate(LocalDate startingDate) {
this.startingDate = startingDate;
}
public int getAvailablePlace() {
return availablePlace;
}
public void setAvailablePlace(int availablePlace) {
this.availablePlace = availablePlace;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public CourseCategory getCourseCategory() {
return courseCategory;
}
public void setCourseCategory(CourseCategory courseCategory) {
this.courseCategory = courseCategory;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
public Level getLevel() {
return level;
}
public int getResImage() {
return resImage;
}
public void setResImage(int resImage) {
this.resImage = resImage;
}
}
Here is the Adapters:
EventAdapter
public class EventViewAdapter extends RecyclerView.Adapter<EventViewAdapter.EventViewHolder> {
ArrayList<Event> eventList;
Context context;
public EventViewAdapter(ArrayList<Event> eventList, Context context) {
this.eventList = eventList;
this.context = context;
}
public EventViewAdapter() {
}
public static class EventViewHolder extends RecyclerView.ViewHolder {
ImageView eventImage;
TextView startingDate, place, title;
LinearLayout cellLayout;
EventViewHolder(View eventView) {
super(eventView);
eventImage = eventView.findViewById(R.id.event_image);
startingDate = eventView.findViewById(R.id.event_starting_date);
place = eventView.findViewById(R.id.event_place);
title = eventView.findViewById(R.id.event_title);
cellLayout = eventView.findViewById(R.id.event_cell_layout);
}
}
#NonNull
#Override
public EventViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.event_cell_def, parent, false);
EventViewHolder evh = new EventViewHolder(view);
return evh;
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, int position) {
final String title = eventList.get(position).getTitle();
final String description = eventList.get(position).getDescription();
final String place = eventList.get(position).getVenue().getCity();
final String address = eventList.get(position).getVenue().getAddress();
final String startDate = String.valueOf(eventList.get(position).getStartingDate().toLocalDate());
final String startTime = String.valueOf(eventList.get(position).getStartingDate().getHour() + ":" + String.valueOf(eventList.get(position).getStartingDate().getMinute()));
final String endDate = String.valueOf(eventList.get(position).getEndingDate().toLocalDate());
final String cost = eventList.get(position).getCost();
final String website = eventList.get(position).getWebsite();
final String category = eventList.get(position).getCategory().getName();
final String organizer = eventList.get(position).getOrganizer().getOrganizer();
final String organizerWebsite = eventList.get(position).getOrganizer().getWebsite();
final int image = eventList.get(position).getResImage();
holder.eventImage.setImageResource(image);
holder.startingDate.setText(startDate);
holder.place.setText(place);
holder.title.setText(title);
holder.cellLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DetailEventActivity.class);
intent.putExtra("title", title);
intent.putExtra("description", description);
intent.putExtra("place", place);
intent.putExtra("address", address);
intent.putExtra("startDate", startDate);
intent.putExtra("startTime", startTime);
intent.putExtra("endDate", endDate);
intent.putExtra("cost", cost);
intent.putExtra("website", website);
intent.putExtra("category", category);
intent.putExtra("organizer", organizer);
intent.putExtra("orgWebsite", organizerWebsite);
intent.putExtra("image", image);
v.getContext().startActivity(intent);
Toast.makeText(context, "Hai premuto su: " + title, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return eventList.size();
}
public void eventSetSearchOperation(ArrayList<Event> newList){
eventList = new ArrayList<>();
eventList.addAll(newList);
notifyDataSetChanged();
}
}
CourseAdapter:
public class CourseViewAdapter extends RecyclerView.Adapter<CourseViewAdapter.CourseViewHolder> {
ArrayList<Course> courseList;
Context context;
public CourseViewAdapter(ArrayList<Course> courseList, Context context) {
this.courseList = courseList;
this.context = context;
}
public CourseViewAdapter(){}
public static class CourseViewHolder extends RecyclerView.ViewHolder {
ImageView courseImage;
TextView startingDate, place, title;
LinearLayout courseLinear;
CourseViewHolder(View courseView){
super(courseView);
courseImage = courseView.findViewById(R.id.course_image);
startingDate = courseView.findViewById(R.id.course_starting_date);
place = courseView.findViewById(R.id.course_place);
title = courseView.findViewById(R.id.course_title);
courseLinear = courseView.findViewById(R.id.course_cell_layout);
}
}
#NonNull
#Override
public CourseViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.course_cell_def, parent, false);
CourseViewHolder cvh = new CourseViewHolder(view);
return cvh;
}
#Override
public void onBindViewHolder(#NonNull CourseViewHolder holder, int position) {
final String title = courseList.get(position).getTitle();
final String category = courseList.get(position).getCourseCategory().getName();
final String description = courseList.get(position).getContent();
final String place = courseList.get(position).getLocation().getName();
final String startDate = String.valueOf(courseList.get(position).getStartingDate());
final int availablePlace = courseList.get(position).getAvailablePlace();
final String teacher = courseList.get(position).getTeacher().getName();
final String teacherEmail = courseList.get(position).getTeacher().getEmail();
final String teacherMobile = courseList.get(position).getTeacher().getPhone();
final String duration = courseList.get(position).getDuration().getName();
final String level = courseList.get(position).getLevel().getName();
final String price = String.valueOf(courseList.get(position).getPrice());
final int image = courseList.get(position).getResImage();
holder.courseImage.setImageResource(image);
holder.startingDate.setText(startDate);
holder.place.setText(place);
holder.title.setText(title);
holder.courseLinear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DetailCourseActivity.class);
intent.putExtra("title", title);
intent.putExtra("category", category);
intent.putExtra("content", description);
intent.putExtra("startDate", startDate);
intent.putExtra("availablePlace", availablePlace);
intent.putExtra("teacher", teacher);
intent.putExtra("teacherEmail", teacherEmail);
intent.putExtra("teacherMobile", teacherMobile);
intent.putExtra("duration", duration);
intent.putExtra("price", price);
intent.putExtra("place", place);
intent.putExtra("level", level);
intent.putExtra("image", image);
v.getContext().startActivity(intent);
Toast.makeText(context, "Hai premuto su: " + title, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return courseList.size();
}
public void courseSetSearchOperation(ArrayList<Course> newList){
courseList = new ArrayList<>();
courseList.addAll(newList);
notifyDataSetChanged();
}
}
News:
public class NewsViewAdapter extends RecyclerView.Adapter<NewsViewAdapter.NewsViewHolder> {
ArrayList<News> newsList;
Context context;
public NewsViewAdapter(ArrayList<News> newsList, Context context) {
this.newsList = newsList;
this.context = context;
}
public NewsViewAdapter(){}
public static class NewsViewHolder extends RecyclerView.ViewHolder {
ImageView newsImage;
TextView newsTitle, newsContent;
LinearLayout newsLayout;
NewsViewHolder(View newView){
super(newView);
newsImage = newView.findViewById(R.id.news_image);
newsTitle = newView.findViewById(R.id.news_title);
newsContent = newView.findViewById(R.id.news_content);
newsLayout = newView.findViewById(R.id.news_cell_layout);
}
}
#NonNull
#Override
public NewsViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_cell_def, parent, false);
NewsViewHolder nvh = new NewsViewHolder(view);
return nvh;
}
#Override
public void onBindViewHolder(#NonNull NewsViewHolder holder, int position) {
final String title = newsList.get(position).getTitle();
final String content = newsList.get(position).getContent();
final int image = newsList.get(position).getResImage();
holder.newsImage.setImageResource(image);
holder.newsTitle.setText(title);
holder.newsContent.setText(content);
holder.newsLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(v.getContext(), DetailNewsActivity.class);
intent.putExtra("title", title);
intent.putExtra("content", content);
intent.putExtra("image", image);
v.getContext().startActivity(intent);
Toast.makeText(context, "Premuto su: " + title, Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount() {
return newsList.size();
}
public void newsSetSearchOperation(ArrayList<News> newList){
newsList = new ArrayList<>();
newsList.addAll(newList);
notifyDataSetChanged();
}
}
Each specific list of item is into a fragment, indeed here is the Main Activity (home), where I would like to display a RecyclerView of all the itmes:
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
private NavigationView mNavigationView;
private Toolbar toolbar;
private ActionBarDrawerToggle drawerToggle;
private FloatingActionButton fab;
private RecyclerView mRecyclerView;
private ImageView openFilter;
private SearchView searchView;
private DataMock dataMock = new DataMock();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view_main);
drawerLayout = findViewById(R.id.drawer_layout);
mNavigationView = findViewById(R.id.nav_view);
toolbar = findViewById(R.id.toolbar);
openFilter = findViewById(R.id.filter_icon);
searchView = findViewById(R.id.action_search);
fab = findViewById(R.id.fab);
fab.show();
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
searchView.setQueryHint(getString(R.string.search_hint));
drawerToggle = setupDrawerToggle();
drawerToggle.setDrawerIndicatorEnabled(true);
drawerToggle.syncState();
drawerLayout.setDrawerListener(drawerToggle);
drawerLayout.setDrawerListener(new DrawerLayout.SimpleDrawerListener() {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
}
});
mNavigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
Fragment nextFragment;
switch (menuItem.getItemId()){
case R.id.event_list:
nextFragment = new EventFragment();
break;
case R.id.course_list:
nextFragment = new CourseFragment();
break;
case R.id.news_list:
nextFragment = new NewsFragment();
break;
default:
throw new IllegalArgumentException("No Fragment for the given menu item");
}
if (nextFragment != null){
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.anchor_point, nextFragment)
.commit();
menuItem.setChecked(true);
setTitle(menuItem.getTitle());
drawerLayout.closeDrawer(mNavigationView);
}
return false;
}
});
openFilter.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
BottomSheetDialog filterDialog = new BottomSheetDialog();
filterDialog.show(getSupportFragmentManager(), "filter dialog opened!");
}
});
// mRecyclerView.setHasFixedSize(true);
// LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// mRecyclerView.setLayoutManager(layoutManager);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
switch (item.getItemId()) {
case android.R.id.home:
drawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private ActionBarDrawerToggle setupDrawerToggle() {
// NOTE: Make sure you pass in a valid toolbar reference. ActionBarDrawToggle() does not require it
// and will not render the hamburger icon without it.
return new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
}
public void backToHome(View view){
for (Fragment fragment : getSupportFragmentManager().getFragments()){
if (fragment != null && (fragment instanceof CourseFragment || fragment instanceof EventFragment || fragment instanceof NewsFragment)){
getSupportFragmentManager().beginTransaction().remove(fragment).commit();
toolbar.setTitle("WePress");
fab.show();
}
}
Toast.makeText(this, "Premuto sul logo", Toast.LENGTH_SHORT).show();
drawerLayout.closeDrawer(mNavigationView);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
drawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggles
drawerToggle.onConfigurationChanged(newConfig);
}
public void addItem(View view){
PopupMenu popupMenu = new PopupMenu(MainActivity.this, fab);
popupMenu.getMenuInflater().inflate(R.menu.fab_main_menu, popupMenu.getMenu());
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()){
case R.id.add_event:
Toast.makeText(MainActivity.this, "Pronti per aggiungere un evento", Toast.LENGTH_SHORT).show();
Intent intentEvent = new Intent(MainActivity.this, AddItemActivity.class);
intentEvent.putExtra("isFrom", "event");
startActivity(intentEvent);
break;
case R.id.add_course:
Toast.makeText(MainActivity.this, "Pronti per aggiungere un corso", Toast.LENGTH_SHORT).show();
Intent intentCourse = new Intent(MainActivity.this, AddItemActivity.class);
intentCourse.putExtra("isFrom", "course");
startActivity(intentCourse);
break;
case R.id.add_news:
Toast.makeText(MainActivity.this, "Pronti per aggiungere una news", Toast.LENGTH_SHORT).show();
Intent intentNews = new Intent(MainActivity.this, AddItemActivity.class);
intentNews.putExtra("isFrom", "news");
startActivity(intentNews);
break;
}
return true;
}
});
popupMenu.show();
}
}
if it's possible to show the list with differents layouts, can you also suggest a way to improve the quality of my code avoiding to repeat lines of code? If I'm not wrong, I would like to re-use each Adapter or part of them that I can put into a specific class (?).
Thank you so much for your help!
If I'm missing some information, please ask me in order to edit the post.
You must do only one adapter (using view type) with a view model class
that contain either an event or a news or a course
the adapter should be something like that:
public class EventViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int TYPE_EVENT = 10;
private static final int TYPE_COURSE = 11;
private static final int TYPE_NEWS = 12;
ArrayList<EventViewModel> eventList;
Context context;
public EventViewAdapter(ArrayList<EventViewModel> eventList, Context context) {
this.eventList = eventList;
this.context = context;
}
public EventViewAdapter() {
}
#Override
public int getItemViewType(int position) {
EventViewModel event = eventList.get(position);
if (event.isEvent()) {
return TYPE_EVENT ;
} else if(event.isCourse()) {
return TYPE_COURSE;
} else {
return TYPE_NEWS;
}
}
public static class EventViewHolder extends RecyclerView.ViewHolder {
ImageView eventImage;
//....
EventViewHolder(View eventView) {
super(eventView);
eventImage = eventView.findViewById(R.id.event_image);
//.....
}
}
public static class CourseViewHolder extends RecyclerView.ViewHolder {
ImageView courseImage;
//.....
CourseViewHolder(View courseView) {
super(courseView);
courseImage = courseView.findViewById(R.id.course_image);
//.....
}
public static class NewsViewHolder extends RecyclerView.ViewHolder {
ImageView newsImage;
//.....
NewsViewHolder(View newView){
super(newView);
newsImage = newView.findViewById(R.id.news_image);
//.....
}
#NonNull
#Override
public RecyclerView.ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
if (viewType == TYPE_EVENT) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.event_cell_def, parent, false);
return new EventViewHolder (rootView);
} else if (viewType == TYPE_COURSE) {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.course_cell_def, parent, false);
return new CourseViewHolder(rootView);
} else {
View rootView = LayoutInflater.from(parent.getContext()).inflate(R.layout.news_cell_def, parent, false);
return new NewsViewHolder(rootView);
}
}
#Override
public void onBindViewHolder(#NonNull EventViewHolder holder, int position)
{
final EventViewModel eventViewModel = eventList.get(position);
if (eventViewModel .isEvent()) {
onBindEvent(holder, eventViewModel.getEvent());
} else if(eventViewModel .isCourse()) {
onBindCourse(holder, eventViewModel.getCourse());
} else {
onBindNews(holder, eventViewModel.getNews());
}
}
private void onBindEvent(RecyclerView.ViewHolder holder, Event event) {
EventViewHolder eventHolder= (EventViewHolder ) holder;
final String title = event.getTitle();
final String description = event.getDescription();
// others ...
holder.eventImage.setImageResource(image);
holder.startingDate.setText(startDate);
// others ...
holder.cellLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
// ...
}
#Override
public int getItemCount() {
return eventList.size();
}
public void eventSetSearchOperation(ArrayList<Event> newList){
eventList = new ArrayList<>();
eventList.addAll(newList);
notifyDataSetChanged();
}
}
And a View Model classes like that :
public class EventViewModel() {
private Event mEvent;
private Course mCourse;
private News mNews;
private EventViewModel(Event event, Course course, News news) {
this.mEvent = event;
this.mCourse = course;
this.mNews = news;
}
public boolean isEvent() {
return mEvent != null
}
public boolean isCourse() {
return mCourse != null
}
public boolean isNews() {
return mNews != null
}
public static EventViewModel getEventInstance(Event event) {
return new EventViewModel(event, null, null
}
public static EventViewModel getCourseInstance(Course course) {
return new EventViewModel(null, course, null
}
public static EventViewModel getNewsInstance(News news) {
return new EventViewModel(null, null, news
}
public Event getEvent() {
return mEvent;
}
public Event getCourse() {
return mScore;
}
public Event getNews() {
return mNews;
}
}
You can use this adapter in all of your fragments (event, course, news) and each fragment contaions a list of EventViewModel with only its specific type. The adapter display in the main activity contains EventViewModel of all types to display all events.
I'm trying to add header to my recylerview so that it will look like <thead> (in HTML table). So, I'm following this tutorial https://en.proft.me/2017/11/25/how-add-custom-header-recylerview/
Here is my adapter
public class Sales_header_adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Sales_header_model> salesheaderlist;
public Sales_header_adapter(List<Sales_header_model> salesheaderlist) {
this.salesheaderlist = salesheaderlist;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if(viewType == ListHeader.TYPE_HEADER) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sales_header_rec_header, parent, false);
return new VHHeader(v);
} else if(viewType == ListHeader.TYPE_ITEM) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.sales_header_rec, parent, false);
return new VHItem(v);
}
throw new RuntimeException("there is no type that matches the type " + viewType + " + make sure your using types correctly");
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof VHHeader) {
Header header = salesheaderlist.get(position);
VHHeader VHheader = (VHHeader)holder;
VHheader.nonota_h.setText(header.getNoNota());
VHheader.tanggal_h.setText(header.getTanggalTransaksi());
VHheader.total_h.setText("Rp. 0");
VHheader.outlet_h.setText(header.getOutletCode());
} else if(holder instanceof VHItem) {
Sales_header_model as = salesheaderlist.get(position);
VHItem VHitem = (VHItem)holder;
VHitem.nonota.setText(as.getNoNota());
VHitem.tanggal.setText(as.getTanggalTransaksi());
VHitem.total.setText("Rp. 0");
VHitem.outlet.setText(as.getOutletCode());
}
}
class VHHeader extends RecyclerView.ViewHolder{
public TextView outlet_h, tanggal_h, total_h,nonota_h;
public VHHeader(View itemView) {
super(itemView);
outlet_h = itemView.findViewById(R.id.tanggalnota);
tanggal_h = itemView.findViewById(R.id.total);
total_h = itemView.findViewById(R.id.nonota);
nonota_h = itemView.findViewById(R.id.outletcode);
}
}
class VHItem extends RecyclerView.ViewHolder{
public TextView outlet, tanggal, total,nonota;
public VHItem(View itemView) {
super(itemView);
tanggal = itemView.findViewById(R.id.tanggalnota);
total = itemView.findViewById(R.id.total);
nonota = itemView.findViewById(R.id.nonota);
outlet = itemView.findViewById(R.id.outletcode);
}
}
#Override
public int getItemViewType(int position) {
return salesheaderlist.get(position).getItemType();
}
#Override
public int getItemCount() {
return salesheaderlist.size();
}
}
and here is my sales_header_model
public class Sales_header_model implements ListHeader {
String OutletCode,TanggalTransaksi,NoNota,CreatedBy,Seller;
String CreatedDate;
Integer Status;
public Sales_header_model(String outletCode, String tanggalTransaksi, String noNota, String createdby, String Seller, String CreatedDate, Integer Status) {
this.OutletCode = outletCode;
this.TanggalTransaksi = tanggalTransaksi;
this.NoNota = noNota;
this.CreatedBy = createdby;
this.Status = Status;
this.Seller = Seller;
this.CreatedDate = CreatedDate;
}
public String getOutletCode() {
return OutletCode;
}
public void setOutletCode(String outletCode) {
OutletCode = outletCode;
}
public String getTanggalTransaksi() {
return TanggalTransaksi;
}
public void setTanggalTransaksi(String tanggalTransaksi) {
TanggalTransaksi = tanggalTransaksi;
}
public String getNoNota() {
return NoNota;
}
public void setNoNota(String noNota) {
NoNota = noNota;
}
public String getCreatedBy() {
return CreatedBy;
}
public void setCreatedBy(String createdBy) {
CreatedBy = createdBy;
}
public String getSeller() {
return Seller;
}
public void setSeller(String seller) {
Seller = seller;
}
public String getCreatedDate() {
return CreatedDate;
}
public void setCreatedDate(String createdDate) {
CreatedDate = createdDate;
}
public Integer getStatus() {
return Status;
}
public void setStatus(Integer status) {
Status = status;
}
public Sales_header_model() {
}
#Override
public int getItemType() {
return ListHeader.TYPE_HEADER;
}
}
My header class
public class Header implements ListHeader {
String OutletCode,TanggalTransaksi,NoNota,Seller;
public String getOutletCode() {
return OutletCode;
}
public void setOutletCode(String outletCode) {
OutletCode = outletCode;
}
public String getTanggalTransaksi() {
return TanggalTransaksi;
}
public void setTanggalTransaksi(String tanggalTransaksi) {
TanggalTransaksi = tanggalTransaksi;
}
public String getNoNota() {
return NoNota;
}
public void setNoNota(String noNota) {
NoNota = noNota;
}
public String getSeller() {
return Seller;
}
public void setSeller(String seller) {
Seller = seller;
}
#Override
public int getItemType() {
return ListHeader.TYPE_HEADER;
}
}
and the listener ListHeader
public interface ListHeader {
int TYPE_ITEM = 0;
int TYPE_HEADER = 1;
int getItemType();
}
The error part is in
if(holder instanceof VHHeader) {
Header header = salesheaderlist.get(position);
VHHeader VHheader = (VHHeader)holder;
VHheader.nonota_h.setText(header.getNoNota());
VHheader.tanggal_h.setText(header.getTanggalTransaksi());
VHheader.total_h.setText("Rp. 0");
VHheader.outlet_h.setText(header.getOutletCode());
}
and here is my error message
error: incompatible types: Sales_header_model cannot be converted to Header
How can i fix it ? thanks in advance
You missed the casting part written in the tutorial. I have added the comments on those parts that you need to change.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof VHHeader) {
//cast the item to respective type
Header header = (Header) salesheaderlist.get(position);
VHHeader VHheader = (VHHeader)holder;
VHheader.nonota_h.setText(header.getNoNota());
VHheader.tanggal_h.setText(header.getTanggalTransaksi());
VHheader.total_h.setText("Rp. 0");
VHheader.outlet_h.setText(header.getOutletCode());
} else if(holder instanceof VHItem) {
//cast the item to respective type
Sales_header_model as = (Sales_header_model) salesheaderlist.get(position);
VHItem VHitem = (VHItem)holder;
VHitem.nonota.setText(as.getNoNota());
VHitem.tanggal.setText(as.getTanggalTransaksi());
VHitem.total.setText("Rp. 0");
VHitem.outlet.setText(as.getOutletCode());
}
}
I am trying to use Firebase Android with a PagerAdapter, but can't seem to find a way to get the data and the child elements from firebase to my pager adapter. Does anyone have some ideas?
Here is my Firebase Data
[ {
"author" : "Rav",
"content" : "This",
"id" : 33,
"image" : "https://firebasestorage.googleapis.com/",
"timestamp" : "13892733894"
}, {
"author" : "Mihail",
"content" : "blalala",
"id" : 44,
"image" : "https://firebasestorage.googleapis.com/",
"timestamp" : 241414212
}]
I am using this PagerAdapter and trying to get the images to it:
public class NovAdapter extends PagerAdapter {
private Context mContext;
private LayoutInflater mLayoutInflater;
private final Utils.LibraryObject[] LIBRARIES = new Utils.LibraryObject[]{
new Utils.LibraryObject(
R.drawable.img_one,
"Лако"),
new Utils.LibraryObject(
R.drawable.img_two,
"Гро"),
new Utils.LibraryObject(
R.drawable.img_tree,
"Ков"),
new Utils.LibraryObject(
R.drawable.img_four,
"Шеф")
};
public NovAdapter(final Context context) {
mContext = context;
mLayoutInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return LIBRARIES.length;
}
#Override
public int getItemPosition(final Object object) {
return POSITION_NONE;
}
#Override
public Object instantiateItem(final ViewGroup container, final int position) {
View view = null;
final ViewHolder holder;
if (view == null) {
view = mLayoutInflater.inflate(R.layout.item, container, false);
holder = new ViewHolder();
holder.img = (ImageView) view.findViewById(R.id.img_item);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
final Utils.LibraryObject libraryObject = LIBRARIES[position];
Picasso.with(view.getContext()).load(libraryObject.getRes()).into(holder.img);
holder.img.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Toast.makeText(mContext, String.valueOf(position) + " " + libraryObject.getGlavi(), Toast.LENGTH_SHORT).show();
}
});
container.addView(view);
return view;
}
#Override
public boolean isViewFromObject(final View view, final Object object) {
return view.equals(object);
}
#Override
public void destroyItem(final ViewGroup container, final int position, final Object object) {
container.removeView((View) object);
}
private static class ViewHolder {
ImageView img;
}
This is the class i am using
public static class LibraryObject {
private String mTitle;
private int mRes;
public LibraryObject(final int res, final String title) {
mRes = res;
mTitle = title;
}
public String getTitle() {
return mTitle;
}
public void setTitle(final String title) {
mTitle = title;
}
public int getRes() {
return mRes;
}
public void setRes(final int res) {
mRes = res;
}
}
}
And this is my Post.class
public class Posts {
private Long id;
private String author;
private String image;
public Posts(){
}
public Posts(Long id, String author, String image) {
this.id = id;
this.author = author;
this.image = image;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
How to show date or today , yesterday like text in between conversation
like whatsapp
MainActivity
public class MainActivity extends AppCompatActivity {
private ChatAdapter chatAdapter;
private RecyclerView recyclerView;
private Context context;
private int loggedInUserID;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindRecyclerView();
// TODO get logged in user id and initialize into 'loggedInUserID'
}
#Override
protected void onResume() {
super.onResume();
getData();
}
private void getData() {
/**
*Your server call to get data and parse json to your appropriate model
* after parsing json to model simply call the
*/
List<ChatModel> chatModelList = ParseData.chatParser(jsonArray);
groupDataIntoHashMap(chatModelList);
}
private void bindRecyclerView() {
chatAdapter = new ChatAdapter(null);
chatAdapter.setUser(loggedInUserID);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(chatAdapter);
}
private void groupDataIntoHashMap(List<ChatModel> chatModelList) {
LinkedHashMap<String, Set<ChatModel>> groupedHashMap = new LinkedHashMap<>();
Set<ChatModel> list = null;
for (ChatModel chatModel : chatModelList) {
//Log.d(TAG, travelActivityDTO.toString());
String hashMapKey = DateParser.convertDateToString(chatModel.getChatTime());
//Log.d(TAG, "start date: " + DateParser.convertDateToString(travelActivityDTO.getStartDate()));
if (groupedHashMap.containsKey(hashMapKey)) {
// The key is already in the HashMap; add the pojo object
// against the existing key.
groupedHashMap.get(hashMapKey).add(chatModel);
} else {
// The key is not there in the HashMap; create a new key-value pair
list = new LinkedHashSet<>();
list.add(chatModel);
groupedHashMap.put(hashMapKey, list);
}
}
//Generate list from map
generateListFromMap(groupedHashMap);
}
private List<ListObject> generateListFromMap(LinkedHashMap<String, Set<ChatModel>> groupedHashMap) {
// We linearly add every item into the consolidatedList.
List<ListObject> consolidatedList = new ArrayList<>();
for (String date : groupedHashMap.keySet()) {
DateObject dateItem = new DateObject();
dateItem.setDate(date);
consolidatedList.add(dateItem);
for (ChatModel chatModel : groupedHashMap.get(date)) {
ChatModelObject generalItem = new ChatModelObject();
generalItem.setChatModel(chatModel);
consolidatedList.add(generalItem);
}
}
chatAdapter.setDataChange(consolidatedList);
return consolidatedList;
}
}
ChatModel.java
public class ChatModel implements Serializable {
private String messageId;
private int userId;
private String firstName;
private String userName;
private String message;
private Date chatTime;
//TODO generate getter and setter
}
ListObject.java (to determind the type of message)
public abstract class ListObject {
public static final int TYPE_DATE = 0;
public static final int TYPE_GENERAL_RIGHT = 1;
public static final int TYPE_GENERAL_LEFT = 2;
abstract public int getType(int userId);
}
DateObject.java
public class DateObject extends ListObject {
private String date;
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
#Override
public int getType(int userId) {
return TYPE_DATE;
}
}
ChatModelObject.java
public class ChatModelObject extends ListObject {
private ChatModel chatModel;
public ChatModel getChatModel() {
return chatModel;
}
public void setChatModel(ChatModel chatModel) {
this.chatModel = chatModel;
}
#Override
public int getType(int userId) {
if (this.chatModel.getUserId() == userId) {
return TYPE_GENERAL_RIGHT;
} else
return TYPE_GENERAL_LEFT;
}
}
DateParse.java to parse date for grouping the chat
public class DateParser {
private static DateFormat dateFormat1 = new SimpleDateFormat("dd/MM/yyyy");
public static String convertDateToString(Date date) {
String strDate = "";
strDate = dateFormat1.format(date);
return strDate;
}
}
ChatAdapter.java
public class ChatAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ListObject> listObjects;
private int loggedInUserId;
public ChatAdapter(List<ListObject> listObjects) {
this.listObjects = listObjects;
}
public void setUser(int userId) {
this.loggedInUserId = userId;
}
public void setDataChange(List<ListObject> asList) {
this.listObjects = asList;
//now, tell the adapter about the update
notifyDataSetChanged();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder = null;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case ListObject.TYPE_GENERAL_RIGHT:
View currentUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_right, parent, false);
viewHolder = new ChatRightViewHolder(currentUserView); // view holder for normal items
break;
case ListObject.TYPE_GENERAL_LEFT:
View otherUserView = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_chat_list_row_left, parent, false);
viewHolder = new ChatLeftViewHolder(otherUserView); // view holder for normal items
break;
case ListObject.TYPE_DATE:
View v2 = inflater.inflate(R.layout.date_row, parent, false);
viewHolder = new DateViewHolder(v2);
break;
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
switch (viewHolder.getItemViewType()) {
case ListObject.TYPE_GENERAL_RIGHT:
ChatModelObject generalItem = (ChatModelObject) listObjects.get(position);
ChatRightViewHolder chatViewHolder = (ChatRightViewHolder) viewHolder;
chatViewHolder.bind(generalItem.getChatModel());
break;
case ListObject.TYPE_GENERAL_LEFT:
ChatModelObject generalItemLeft = (ChatModelObject) listObjects.get(position);
ChatLeftViewHolder chatLeftViewHolder = (ChatLeftViewHolder) viewHolder;
chatLeftViewHolder.bind(generalItemLeft.getChatModel());
break;
case ListObject.TYPE_DATE:
DateObject dateItem = (DateObject) listObjects.get(position);
DateViewHolder dateViewHolder = (DateViewHolder) viewHolder;
dateViewHolder.bind(dateItem.getDate());
break;
}
}
#Override
public int getItemCount() {
if (listObjects != null) {
return listObjects.size();
}
return 0;
}
#Override
public int getItemViewType(int position) {
return listObjects.get(position).getType(loggedInUserId);
}
public ListObject getItem(int position) {
return listObjects.get(position);
}
}
ChatRightViewHolder.java for current user message
public class ChatRightViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatRightViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
ChatLeftViewHolder.java for display other user messages.
public class ChatLeftViewHolder extends RecyclerView.ViewHolder {
private final String TAG = ChatRightViewHolder.class.getSimpleName();
public ChatLeftViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final ChatModel chatModel) {
//TODO set data to xml view via textivew.setText();
}
}
DateViewHolder.java to display date
public class DateViewHolder extends RecyclerView.ViewHolder {
public DateViewHolder(View itemView) {
super(itemView);
//TODO initialize your xml views
}
public void bind(final String date) {
//TODO set data to xml view via textivew.setText();
}
}
You need to create a new ViewHolder for that purpose
For example:
// Different types of rows
private static final int TYPE_ITEM_LEFT = 0;
private static final int TYPE_ITEM_RIGHT = 1;
private static final int TYPE_ITEM_DATE_CONTAINER = 2;
public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
class ViewHolder0 extends RecyclerView.ViewHolder {
// Viewholder for row type 0
}
class ViewHolder1 extends RecyclerView.ViewHolder {
// Viewholder for row type 1
}
class ViewHolder2 extends RecyclerView.ViewHolder {
// Viewholder for row type 2
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
if (viewHolder.getItemViewType() == TYPE_ITEM_LEFT) {
// Code to populate type 0 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_RIGHT) {
// Code to populate type 1 view here
} else if (viewHolder.getItemViewType() == TYPE_ITEM_DATE_CONTAINER) {
// Code to populate type 2 view here
}
}
You just have to compare the date when scrolling and set the visibility of date view. The advantage of this is there's no hard-coded today/yesterday in data list and is able to refresh the correct date immediately (scrolling) after 12.00 a.m.
e.g. in your onBindViewHolder() in recycleview:
if (position != 0) {
processDate(holder.topDateTextView, myData.getDate()
, this.myDataList.get(position - 1).getDate()
, false)
;
} else {
processDate(holder.topDateTextView, data.getDay()
, null
, true)
;
}
Method to process that date view (Assume your list has format "dd/MM/yyyy"):
private void processDate(#NonNull TextView tv, String dateAPIStr
, String dateAPICompareStr
, boolean isFirstItem) {
SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
if (isFirstItem) {
//first item always got date/today to shows
//and overkill to compare with next item flow
Date dateFromAPI = null;
try {
dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
if (!dateAPIStr.equalsIgnoreCase(dateAPICompareStr)) {
try {
Date dateFromAPI = f.parse(dateAPIStr);
if (DateUtils.isToday(dateFromAPI.getTime())) tv.setText("today");
else if (DateUtils.isToday(dateFromAPI.getTime() + DateUtils.DAY_IN_MILLIS)) tv.setText("yesterday");
else tv.setText(dateAPIStr);
tv.setIncludeFontPadding(false);
tv.setVisibility(View.VISIBLE);
} catch (ParseException e) {
e.printStackTrace();
tv.setVisibility(View.GONE);
}
} else {
tv.setVisibility(View.GONE);
}
}
}
Note: You also need to do yourAdapter.notifyDataSetChanged(); if append new item to redraw to dismiss previous "today"/date after 12.00 a.m on the same page, not just rely on yourAdapter.notifyItemInserted(new_item_position) which doesn't redraw previous items.