Inter-changing LayoutInflator View using if statements - android

I am trying to make an App that enables users to interact using text messages and audio messages. I am able to send and retrieve messages but the problem i'm facing is that i am getting an NullPointerException when i try to check whether the received message is a text or an audio. What i want to do is first check the text type, after that choose an appropriate Layout view based on the message type. I used adapter and this is my code:
public class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MyMessageViewHolder>{
private ArrayList<Messages> arrayListMessages= new ArrayList<>();
private Context mcontext;
FirebaseAuth mAuth;
private String Type = null;
public static class myAudioMessageViewHolder extends RecyclerView.ViewHolder{
TextView rec_start;
TextView rec_end;
ImageButton myPlay;
SeekBar audio_seek;
public myAudioMessageViewHolder(View itemView){
super(itemView);
rec_start = itemView.findViewById(R.id.time_elapsed);
rec_end = itemView.findViewById(R.id.finish_time);
myPlay = itemView.findViewById(R.id.play_btn);
audio_seek = itemView.findViewById(R.id.my_seekbar);
}
}
public static class MyMessageViewHolder extends RecyclerView.ViewHolder{
TextView textViewMessage;
CircleImageView UserProfile;
public MyMessageViewHolder(View itemView) {
super(itemView);
textViewMessage = itemView.findViewById(R.id.messageTextView);
UserProfile = itemView.findViewById(R.id.message_profile_layout);
}
}
public ArrayAdapter adapter;
public MessageAdapter(Context context, ArrayList<Messages> arrayListMessages){
this.arrayListMessages = arrayListMessages;
mcontext = context;
}
#Override
public MyMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType ) {
if (Type.equals("audio")){ // This should be the determinant on the view being chosen and it should call type from database
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.audio_message_layout, parent, false);
return new MyMessageViewHolder(view);
}else if (Type.equals("text")){
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout, parent,false);
return new MyMessageViewHolder(view);
}
else {
return null;
}
}
#Override
public void onBindViewHolder(final MyMessageViewHolder holder, final int position) {
mAuth = FirebaseAuth.getInstance();
String mCurrentUser = mAuth.getCurrentUser().getUid();
final Messages messages = arrayListMessages.get(position);
String message_type = messages.getType();
String from_user = messages.getFrom();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(from_user);
if(mCurrentUser.equals(messages.getFrom())){
holder.textViewMessage.setBackgroundResource(R.drawable.custom_message_bg_primary);
holder.textViewMessage.setTextIsSelectable(true);
holder.textViewMessage.setGravity(Gravity.RIGHT);
holder.textViewMessage.setTextColor(Color.WHITE);
holder.textViewMessage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view)
{
CharSequence options[] = new CharSequence[]{"Delete", "Copy Text"};
final AlertDialog.Builder builder = new AlertDialog.Builder(mcontext);
builder.setTitle("Select Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Click Event for each item.
if (i == 0) {
String selectedItem = messages.getMessage();
arrayListMessages.remove(selectedItem);
Toast.makeText(mcontext, "Message deleted", Toast.LENGTH_SHORT).show();
}
if (i == 1)
{
ClipboardManager cm = (ClipboardManager) mcontext.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(holder.textViewMessage.getText());
Toast.makeText(mcontext, "Copied to clipboard", Toast.LENGTH_SHORT).show();
}
}
});
builder.show();
return true;
}
});
}else{
holder.textViewMessage.setBackgroundResource(R.drawable.custom_message_bd_white);
holder.textViewMessage.setTextIsSelectable(true);
holder.textViewMessage.setGravity(Gravity.LEFT);
holder.textViewMessage.setTextColor(Color.BLACK);
holder.textViewMessage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
CharSequence options[] = new CharSequence[]{"Delete", "Copy Text"};
final AlertDialog.Builder builder = new AlertDialog.Builder(mcontext);
builder.setTitle("Select Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Click Event for each item.
if (i == 0) {
String selectedItem = messages.getMessage();
arrayListMessages.remove(selectedItem);
adapter.notifyDataSetChanged();
Toast.makeText(mcontext, "Message deleted", Toast.LENGTH_SHORT).show();
}
if (i == 1)
{
ClipboardManager cm = (ClipboardManager) mcontext.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(holder.textViewMessage.getText());
Toast.makeText(mcontext, "Copied to clipboard", Toast.LENGTH_SHORT).show();
}
}
});
builder.show();
return true;
}
});
}
holder.textViewMessage.setText(messages.getMessage());
if(message_type.equals("text")) {
Type = messages.getType(); // Here i am trying to get the message type and then use it to get Inflator view of a text type
holder.textViewMessage.setText(messages.getMessage());
}
else if(message_type.equals("audio"))
{
Type = messages.getType(); // Here i am trying to get the message type and then use it to get Inflator view of a audio type
}
}
#Override
public int getItemCount() {
return arrayListMessages.size();
}
}
This is where i get the Messages from :
public class Messages {
String message,type,from;
long time;
boolean seen;
public Messages(){
// for datashnap shot
}
public Messages(String message, String type, long time, boolean seen, String from) {
this.message = message;
this.type = type;
this.time = time;
this.seen = seen;
this.from=from;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public boolean isSeen() {
return seen;
}
public void setSeen(boolean seen) {
this.seen = seen;
}
}
After Running the App on a device, i got the following error:
FATAL EXCEPTION: main
Process: com.rescuex_za.rescuex, PID: 22285
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
at com.rescuex_za.rescuex.MessageAdapter.onCreateViewHolder(MessageAdapter.java:92)
at com.rescuex_za.rescuex.MessageAdapter.onCreateViewHolder(MessageAdapter.java:37)
at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6519)
I am getting and checking the messages from my database. How can i read the message type? Please provide full details or suggestions as i am still new to android development and want to understand what i am doing. Thank you.
after Following the approach suggested by AL. I am not getting the view i am looking for this is the updates of the classes i posted when i asked the question.
1.Messages class
public class Messages {
public static final int TEXT_TYPE=0;
public static final int AUDIO_TYPE=1;
String message,type,from;
long time;
boolean seen;
int type_text;
public Messages(){
// for datashnap shot
}
public Messages(String message, String type, long time, boolean seen, String from) {
this.message = message;
this.type = type;
this.time = time;
this.seen = seen;
this.from=from;
if (type.equals("text")){
this.type_text=TEXT_TYPE;
} else if (type.equals("recording")){
this.type_text=AUDIO_TYPE;
}
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public boolean isSeen() {
return seen;
}
public void setSeen(boolean seen) {
this.seen = seen;
}
}
This is my Adapter class
public class MessageAdapter extends
RecyclerView.Adapter<MessageAdapter.MyMessageViewHolder>{
private ArrayList<Messages> arrayListMessages= new ArrayList<>();
private Context mcontext;
FirebaseAuth mAuth;
private DatabaseReference mUserDatabase;
private ViewGroup parent;
public static class myAudioMessageViewHolder extends MyMessageViewHolder{
TextView rec_start;
TextView rec_end;
ImageButton myPlay;
SeekBar audio_seek;
public myAudioMessageViewHolder(View itemView){
super(itemView);
rec_start = itemView.findViewById(R.id.time_elapsed);
rec_end = itemView.findViewById(R.id.finish_time);
myPlay = itemView.findViewById(R.id.play_btn);
audio_seek = itemView.findViewById(R.id.my_seekbar);
}
}
public static class MyMessageViewHolder extends RecyclerView.ViewHolder{
TextView textViewMessage;
CircleImageView UserProfile;
public MyMessageViewHolder(View itemView) {
super(itemView);
textViewMessage = itemView.findViewById(R.id.messageTextView);
UserProfile = itemView.findViewById(R.id.message_profile_layout);
}
}
public ArrayAdapter adapter;
public MessageAdapter(Context context, ArrayList<Messages> arrayListMessages){
this.arrayListMessages = arrayListMessages;
mcontext = context;
}
#Override
public MyMessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType ) {
View view;
switch (viewType) {
case Messages.TEXT_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_single_layout, parent, false);
return new myAudioMessageViewHolder(view);
case Messages.AUDIO_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.audio_message_layout, parent, false);
return new MyMessageViewHolder(view);
}
return null;
}
#Override
public int getItemViewType(int position) {
switch (arrayListMessages.get(position).type_text) {
case 0:
return Messages.TEXT_TYPE;
case 1:
return Messages.AUDIO_TYPE;
default:
return -1;
}
}
#Override
public void onBindViewHolder(final MyMessageViewHolder holder, final int position) {
mAuth = FirebaseAuth.getInstance();
String mCurrentUser = mAuth.getCurrentUser().getUid();
final Messages messages = arrayListMessages.get(position);
String message_type = messages.getType();
String from_user = messages.getFrom();
mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(from_user);
if(mCurrentUser.equals(messages.getFrom())){
holder.textViewMessage.setBackgroundResource(R.drawable.custom_message_bg_primary);
holder.textViewMessage.setTextIsSelectable(true);
holder.textViewMessage.setGravity(Gravity.RIGHT);
holder.textViewMessage.setTextColor(Color.WHITE);
holder.textViewMessage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view)
{
CharSequence options[] = new CharSequence[]{"Delete", "Copy Text"};
final AlertDialog.Builder builder = new AlertDialog.Builder(mcontext);
builder.setTitle("Select Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Click Event for each item.
if (i == 0) {
String selectedItem = messages.getMessage();
arrayListMessages.remove(selectedItem);
Toast.makeText(mcontext, "Message deleted", Toast.LENGTH_SHORT).show();
}
if (i == 1)
{
ClipboardManager cm = (ClipboardManager) mcontext.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(holder.textViewMessage.getText());
Toast.makeText(mcontext, "Copied to clipboard", Toast.LENGTH_SHORT).show();
}
}
});
builder.show();
return true;
}
});
}else{
holder.textViewMessage.setBackgroundResource(R.drawable.custom_message_bd_white);
holder.textViewMessage.setTextIsSelectable(true);
holder.textViewMessage.setGravity(Gravity.LEFT);
holder.textViewMessage.setTextColor(Color.BLACK);
holder.textViewMessage.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
CharSequence options[] = new CharSequence[]{"Delete", "Copy Text"};
final AlertDialog.Builder builder = new AlertDialog.Builder(mcontext);
builder.setTitle("Select Options");
builder.setItems(options, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Click Event for each item.
if (i == 0) {
String selectedItem = messages.getMessage();
arrayListMessages.remove(selectedItem);
adapter.notifyDataSetChanged();
Toast.makeText(mcontext, "Message deleted", Toast.LENGTH_SHORT).show();
}
if (i == 1)
{
ClipboardManager cm = (ClipboardManager) mcontext.getSystemService(Context.CLIPBOARD_SERVICE);
cm.setText(holder.textViewMessage.getText());
Toast.makeText(mcontext, "Copied to clipboard", Toast.LENGTH_SHORT).show();
}
}
});
builder.show();
return true;
}
});
}
holder.textViewMessage.setText(messages.getMessage());
if(message_type.equals("text")) {
// Here i am trying to get the message type and then use it to get Inflator view of a text type
holder.textViewMessage.setText(messages.getMessage());
}
else if(message_type.equals("recording"))
{
// Here i am trying to get the message type and then use it to get Inflator view of a audio type
}
}
#Override
public int getItemCount() {
return arrayListMessages.size();
}
}

Related

RecyclerView with different types and different adapter

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.

RecyclerView messes up when scrolling

I never asked any question before but hope you'll get my point.
I am making a chat app in which I am using a RecyclerView to show messages. The problem is when I scroll the RecyclerView some of the items disappear from the top and the whole items messes up when I try to add a message it doesn't even scroll to bottom nor added in the ListView.
Here is my RecyclerView:
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation_recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:layout_above="#id/typingConversationLayout"
android:layout_below="#id/topLayout_conversation_activity"
android:layout_marginBottom="-5dp"
android:paddingBottom="7dp" />
Initializing and setting the RecycerView:
linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);
Here is my Adapter class:
private class ConversationRecyclerViewAdapter
extends RecyclerView.Adapter<ConversationRecyclerViewAdapter.ConversationViewHolder> {
#NonNull
#Override
public ConversationViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
Log.d(TAG, "onCreateViewHolder: Users Find started");
View conversationsView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.layout_message_received, parent, false);
return new ConversationViewHolder(conversationsView);
}
#Override
public void onBindViewHolder(#NonNull final ConversationViewHolder holderConversation, int i) {
Log.d(TAG, "onBindViewHolder: Users Find started at position is " + i);
final int position = holderConversation.getAdapterPosition();
if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);
holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));
} else {
holderConversation.sentMsgLayout.setVisibility(View.GONE);
holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));
}
Log.d(TAG, "onBindViewHolder: completed at " + position);
}
#Override
public int getItemCount() {
return mOwnUser_1.size();
}
public class ConversationViewHolder extends RecyclerView.ViewHolder {
RelativeLayout receivedMsgLayout, sentMsgLayout;
EmojiTextView receivedMsg, sentMsg;
CircleImageView receivedProfileImg, sentProfileImg;
public ConversationViewHolder(#NonNull View v) {
super(v);
receivedMsgLayout = v.findViewById(R.id.received_message_layout);
sentMsgLayout = v.findViewById(R.id.sent_message_layout);
receivedMsg = v.findViewById(R.id.received_message_text);
sentMsg = v.findViewById(R.id.sent_message_text);
receivedProfileImg = v.findViewById(R.id.received_message_user__profile_image);
sentProfileImg = v.findViewById(R.id.sent_message_user__profile_image);
}
}
}
Here I am adding data to ListView and displaying to the RecyclerView:
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = editText.getText().toString().trim();
if (TextUtils.isEmpty(msg)) {
editText.setError("Please add a message");
editText.requestFocus();
} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");
mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);
editText.setText("");
editText.requestFocus();
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
}
}
});
I don't know what i am doing wrong but it does not seem to work as i wanted.
Update Code:
The three listviews:
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();
And the way of adding data to adapter:
mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy);
mUserText_3.add(edittext.getText().toString().trim());
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
My Whole Conversation Activity Class:
public class ConversationActivity extends AppCompatActivity {
private static final String TAG = "ConversationActivity";
private EditText editText;
private LinearLayout linearLayout;
private LinearLayoutManager linearLayoutManager;
private ImageView sendBtn;
private ImageView emojiImage;
private View rootView;
private Boolean popUpShown = false;
private Boolean micShown = false;
private ImageView micBtn;
private RelativeLayout micLayout;
private RecyclerView conversationRecyclerView;
// Array Lists for Find USERS
private ArrayList<Boolean> mOwnUser_1 = new ArrayList<>();
private ArrayList<Integer> mUserProfileImg_2 = new ArrayList<>();
private ArrayList<String> mUserText_3 = new ArrayList<>();
private ConversationRecyclerViewAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate: started");
super.onCreate(savedInstanceState);
EmojiManager.install(new TwitterEmojiProvider());
setContentView(R.layout.activity_conversation);
editText = findViewById(R.id.conversationEditText);
linearLayout = findViewById(R.id.optionsOther);
emojiImage = findViewById(R.id.emojiIconOther);
rootView = findViewById(R.id.root_view_conversation);
micBtn = findViewById(R.id.microphoneBtn);
micLayout = findViewById(R.id.microphoneLayout);
conversationRecyclerView = findViewById(R.id.conversation_recyclerView);
sendBtn = findViewById(R.id.sendBtnConversation);
if (!(Build.VERSION.SDK_INT >= 21))
findViewById(R.id.typingConversationLayout).setBackgroundResource(R.drawable.edit_text_conversation_background_below_api);
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String msg = editText.getText().toString().trim();
if (TextUtils.isEmpty(msg)) {
editText.setError("Please add a message");
editText.requestFocus();
} else {
Log.d(TAG, "onClick: send Btn ADDED TEXT.. ");
addData(true, R.drawable.boy0, msg);
}
}
});
initConversationArrayList();
}
private void addData(Boolean user, int image, String message) {
mOwnUser_1.add(user);
mUserProfileImg_2.add(image);
mUserText_3.add(message);
editText.setText("");
editText.requestFocus();
adapter.notifyItemInserted(mOwnUser_1.size());
conversationRecyclerView.scrollToPosition(mOwnUser_1.size() - 1);
}
private void initConversationArrayList() {
Log.d(TAG, "initConversationArrayList: created");
mOwnUser_1.add(true);
mUserProfileImg_2.add(R.drawable.boy0);
mUserText_3.add("Hello How are you?");
Log.d(TAG, "initConversationArrayList: completed");
initConversationRecyclerView();
}
private void initConversationRecyclerView() {
Log.d(TAG, "initConversationRecyclerView: started");
linearLayoutManager = new LinearLayoutManager(this);
adapter = new ConversationRecyclerViewAdapter();
conversationRecyclerView.setAdapter(adapter);
conversationRecyclerView.setLayoutManager(linearLayoutManager);
linearLayoutManager.setStackFromEnd(true);
conversationRecyclerView.setHasFixedSize(true);
conversationRecyclerView.setNestedScrollingEnabled(false);
Log.d(TAG, "initConversationRecyclerView: completed");
}
Currently I am also working on chat module, let me show you how am I doing this. I am going to show you in steps.
Step 1: make two separate layout for recyclerview items, one for message that has been sent from your side and one for message received from another side.
Step 2 : make two view holders to populate different layout according to your scenario, made in above step, like this:
public class ChatNewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Chat> chats;
public ChatNewAdapter(List<Chat> chats) {
this.chats = chats;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
if (viewType == 0) {
View viewSend = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_send, parent, false);
return new ViewHolderSend(viewSend);
} else {
View viewReceive = (View) LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new ViewHolderReceive(viewReceive);
}
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case 0:
ViewHolderSend viewHolderSend = (ViewHolderSend) holder;
viewHolderSend.messageSend.setText(chats.get(position).getMessage());
break;
case 1:
ViewHolderReceive viewHolderReceive = (ViewHolderReceive) holder;
viewHolderReceive.messageReceived.setText(chats.get(position).getMessage());
break;
}
}
#Override
public int getItemCount() {
return chats.size();
}
#Override
public int getItemViewType(int position) {
if (chats != null && !chats.get(position).fromAdmin) {
return 0;
} else
return 1;
}
class ViewHolderSend extends RecyclerView.ViewHolder {
TextView messageSend;
public ViewHolderSend(View itemView) {
super(itemView);
messageSend = (TextView) itemView.findViewById(R.id.messageSend);
}
}
class ViewHolderReceive extends RecyclerView.ViewHolder {
TextView messageReceived;
public ViewHolderReceive(View itemView) {
super(itemView);
messageReceived = (TextView) itemView.findViewById(R.id.messageReceived);
}
}
public int addMessages(Chat chat) {
chats.add(chat);
notifyDataSetChanged();
return chats.size();
}
Step 3 : now in your activity:
public class Test extends AppCompatActivity {
RecyclerView chatList;
RecyclerView.LayoutManager mLayoutManager;
ChatNewAdapter adapter;
ImageView sendButton;
EditText messageEditText;
boolean keyboardUp = false;
boolean isRunning = false;
ArrayList<Chat> chats;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
isRunning = true;
setUpComponents();
}
public void setUpComponents() {
chatList = (RecyclerView) findViewById(R.id.chat_list);
chatList.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this);
chatList.setLayoutManager(mLayoutManager);
messageEditText = (EditText) findViewById(R.id.messageText);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
sendButton = (ImageView) findViewById(R.id.send);
adapter = new ChatNewAdapter(chats);
chatList.setAdapter(adapter);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);
messageEditText.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (keyboardShown(messageEditText.getRootView())) {
Log.d("keyboard", "keyboard UP");
if (keyboardUp == false) {
if (chats.size() > 0)
chatList.smoothScrollToPosition(chats.size() + 1);
keyboardUp = true;
}
} else {
Log.d("keyboard", "keyboard Down");
keyboardUp = false;
}
}
});
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final String message = messageEditText.getText().toString().trim();
if (!message.equals("")) {
Chat chat = new Chat();
String name = message;
chat.setMessage(name);
messageEditText.setText("");
adapter.addMessages(chat);
chatList.scrollToPosition(chatList.getAdapter().getItemCount() - 1);
} else {
Log.d("sending message Error", "error fetching dates");
}
}
});
}
private boolean keyboardShown(View rootView) {
final int softKeyboardHeight = 100;
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
DisplayMetrics dm = rootView.getResources().getDisplayMetrics();
int heightDiff = rootView.getBottom() - r.bottom;
return heightDiff > softKeyboardHeight * dm.density;
}
And this is my model class, ignore #PrimaryKey and #Required annotation it just because I am using Realm for local DB. In your case you wont required these annotation.
public class Chat extends RealmObject {
#PrimaryKey
#Required
public Long id;
public boolean fromAdmin;
#Required
public String message;
public int type;
public boolean isRead;
public boolean isSent;
public Date date;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public boolean isFromAdmin() {
return fromAdmin;
}
public void setFromAdmin(boolean fromAdmin) {
this.fromAdmin = fromAdmin;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public boolean isRead() {
return isRead;
}
public void setRead(boolean read) {
isRead = read;
}
public boolean isSent() {
return isSent;
}
public void setSent(boolean sent) {
isSent = sent;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
I hope it will be helpful for you, you can ask further if you want to know anything else related to code.
RecyclerView as the name stands recycles the views. When binding data to a view, you need to ensure you set or reset all views that are touched in the adapter. Messups typically occur when there's data that is set only conditionally for some but not all items.
In particular:
if (mOwnUser_1.get(position)) {
holderConversation.receivedMsgLayout.setVisibility(View.GONE);
holderConversation.sentProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.sentMsg.setText(mUserText_3.get(position));
} else {
holderConversation.sentMsgLayout.setVisibility(View.GONE);
holderConversation.receivedProfileImg.setImageResource(mUserProfileImg_2.get(position));
holderConversation.receivedMsg.setText(mUserText_3.get(position));
}
Both of these branches will need to reset the other layout back to visible.
Anyway with this kind of two-layout approach you are likely better off by having them as separate view types in your adapter. See How to create RecyclerView with multiple view type?

Chat RecyclerView is blank, Showing nothing but Data is being fetched

I am trying to show Recyclerview in chat form, but it is blank can't find the issue here is the code, I don't know where the issue is but it might be in adapter.
MessageListAdapter.java
public class MessageListAdapter extends RecyclerView.Adapter {
private static final int VIEW_TYPE_MESSAGE_SENT = 1;
private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
private Context mContext;
private List<ItemMessage> mMessageList;
public MessageListAdapter(Context context, List<ItemMessage> messageList) {
mContext = context;
mMessageList = messageList;
}
#Override
public int getItemCount() {
return mMessageList.size();
}
// Determines the appropriate ViewType according to the sender of the message.
#Override
public int getItemViewType(int position) {
ItemMessage message = mMessageList.get(position);
if (message.getSender().equals(FirebaseAuth.getInstance().getCurrentUser().getUid())) {
// If the current user is the sender of the message
return VIEW_TYPE_MESSAGE_SENT;
} else {
// If some other user sent the message
return VIEW_TYPE_MESSAGE_RECEIVED;
}
}
// Inflates the appropriate layout according to the ViewType.
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_MESSAGE_SENT) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_sent, parent, false);
return new SentMessageHolder(view);
} else if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_message_received, parent, false);
return new ReceivedMessageHolder(view);
}
return null;
}
// Passes the message object to a ViewHolder so that the contents can be bound to UI.
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
ItemMessage message = mMessageList.get(position);
switch (holder.getItemViewType()) {
case VIEW_TYPE_MESSAGE_SENT:
((SentMessageHolder) holder).bind(message);
break;
case VIEW_TYPE_MESSAGE_RECEIVED:
((ReceivedMessageHolder) holder).bind(message);
}
}
private class SentMessageHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText;
SentMessageHolder(View itemView) {
super(itemView);
messageText = (TextView) itemView.findViewById(R.id.text_message_body);
timeText = (TextView) itemView.findViewById(R.id.text_message_time);
}
void bind(ItemMessage message) {
messageText.setText(message.getMessgae());
// Format the stored timestamp into a readable String using method.
timeText.setText(message.getTime());
}
}
private class ReceivedMessageHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText, nameText;
ImageView profileImage;
ReceivedMessageHolder(View itemView) {
super(itemView);
messageText = (TextView) itemView.findViewById(R.id.text_message_body);
timeText = (TextView) itemView.findViewById(R.id.text_message_time);
nameText = (TextView) itemView.findViewById(R.id.text_message_name);
profileImage = (ImageView) itemView.findViewById(R.id.image_message_profile);
}
void bind(ItemMessage message) {
messageText.setText(message.getMessgae());
// Format the stored timestamp into a readable String using method.
timeText.setText(message.getTime());
nameText.setText("kdkdk");
// Insert the profile image from the URL into the ImageView.
// Utils.displayRoundImageFromUrl(mContext, message.getSender().getProfileUrl(), profileImage);
}
}
}
ItemMessage.java
public class ItemMessage {
private String sender = null;
private String reciever = null;
private String time = null;
private String messgae = null;
public ItemMessage() {
}
public ItemMessage(String sender, String reciever, String time, String messgae) {
this.sender = sender;
this.reciever = reciever;
this.time = time;
this.messgae = messgae;
}
public String getSender() {
return sender;
}
public void setSender(String sender) {
this.sender = sender;
}
public String getReciever() {
return reciever;
}
public void setReciever(String reciever) {
this.reciever = reciever;
}
public String getTime() {
return time;
}
public void setTime(String time) {
this.time = time;
}
public String getMessgae() {
return messgae;
}
public void setMessgae(String messgae) {
this.messgae = messgae;
}
}
fetching code.
childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ItemMessage itemMessage = dataSnapshot.getValue(ItemMessage.class);
friendlyMessages.add(itemMessage);
mMessageAdapter.notifyDataSetChanged();
Log.d("SSSSz" , friendlyMessages.size()+"");
Log.d("SSSSz", itemMessage.getMessgae());
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
databaseReferencemsg.addChildEventListener(childEventListener);
I am not posting rest of the code because I know issue is here.

RecyclerView filled with Objects from SharedPreferences is slow and laggy

I am building an app which has a RecyclerView which holds Objects that are retrieved from SharedPreferences.
Unfortunately the RecyclerView is lagging when it is binded.
This is my Adapter
public class ShiftAdapter extends RecyclerView.Adapter<ShiftAdapter.ViewHolder>{
private List<Shift> mDataSet;
private Context mContext;
private static final String TAG = "ShiftAdapter";
public int previousExpandedPosition = -1;
public int mExpandedPosition = -1;
private static SharedPreferences mPrefs;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Boolean isStart;
private Date shiftIn;
private Date shiftOut;
private Date mDate;
public EditText mshiftInText;
public EditText mshiftOutText;
public Date date;
public ShiftAdapter(Context context, List<Shift> list) {
mDataSet = list;
mContext = context;
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView mDate;
public TextView mTime;
public TextView mPay;
public RelativeLayout mRelativeLayout;
public LinearLayout mExepandableLayout;
public Date mshiftIn;
public Date mshiftOut;
public EditText mshiftInText;
public EditText mshiftOutText;
public Button mUpdateButton;
public Button mDeleteButton;
public ViewHolder(View v) {
super(v);
mDate = (TextView) v.findViewById(R.id.date_TV);
mTime = (TextView) v.findViewById(R.id.time_TV);
mPay = (TextView) v.findViewById(R.id.pay_TV);
mRelativeLayout = (RelativeLayout) v.findViewById(R.id.rel_layout);
mExepandableLayout = (LinearLayout) v.findViewById(R.id.expandableLayout);
mshiftInText = (EditText) v.findViewById(R.id.setShiftIn);
mshiftOutText = (EditText) v.findViewById(R.id.setShiftOut);
mUpdateButton = (Button) v.findViewById(R.id.updateButton);
mDeleteButton = (Button) v.findViewById(R.id.deleteButton);
}
}
#Override
public ShiftAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(mContext)
.inflate(R.layout.shift, parent, false);
ViewHolder vh = new ViewHolder(itemView);
return vh;
}
//TODO:Bind all the view elements to Shift Properties
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int i) {
// Format double
String hours = new DecimalFormat("##.##").format(mDataSet.get(i).getHours());
String pay = new DecimalFormat("##.##").format(mDataSet.get(i).getPay());
//set the Text
holder.mTime.setText(hours);
holder.mDate.setText(mDataSet.get(i).dateToString());
holder.mPay.setText(pay);
Log.d(TAG, "onBindViewHolder: called");
// new AsyncTask<>().ex
//Expand mExapndableLayout
final int position = i;
final boolean isExpanded = position ==mExpandedPosition;
holder.mExepandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
holder.itemView.setActivated(isExpanded);
// //set shift Times
// shiftIn = mDataSet.get(position).getInDate();
// shiftOut = mDataSet.get(position).getInDate();
if (isExpanded)
previousExpandedPosition = position;
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mExpandedPosition = isExpanded ? -1:position;
notifyItemChanged(previousExpandedPosition);
notifyItemChanged(position);
}
});
//fill expandable layout
holder.mshiftInText.setText(mDataSet.get(position).fullTimeToString(0));
final EditText in = holder.mshiftInText;
final EditText out = holder.mshiftOutText;
//edit mShiftIn Text
holder.mshiftInText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =true;
timePickerDialog(in,out);
}
});
holder.mshiftOutText.setText(mDataSet.get(position).fullTimeToString(1));
//edit MshiftOut Text
holder.mshiftOutText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isStart =false;
timePickerDialog(in,out);
}
});
//updateButton onClick
holder.mUpdateButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
shiftIn = mDataSet.get(position).getInDate();
shiftOut = mDataSet.get(position).getOutDate();
if(Validate.getValidate().isDateValid(shiftIn,shiftOut)) {
SharedPrefs.getInstance(mContext).editShift(newShift(shiftIn, shiftOut),Integer.toString(position));
int length = SharedPrefs.getInstance(mContext).getLength() - 1;
if (SharedPrefs.getInstance(mContext).getShift(length) != null) {
Log.d(TAG, "Edit Shift onClick: Success");
SharedPrefs.getInstance(mContext).saveShiftList(SharedPrefs.getInstance(mContext).sortList(SharedPrefs.getInstance(mContext).getShiftList()));
ShiftsFragment.updateUI();
Toast.makeText(mContext, "success", Toast.LENGTH_SHORT).show();
}
} else {
mShiftOut.setBackgroundResource(R.drawable.red_border);
Toast.makeText(mContext, "error", Toast.LENGTH_SHORT).show(); }
} catch(Exception e){
Log.d(TAG, "onDateSelected: "+e.toString());
Toast.makeText(mContext,"update FAIL", Toast.LENGTH_SHORT).show();
}
// update the Shift
}
});
holder.mDeleteButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
areYouSure(mExpandedPosition);
}
});
}
#Override
public int getItemCount() {
return mDataSet.size();
}
public Date timePickerDialog(EditText in,EditText out) {
mshiftInText = in;
mshiftOutText = out;
new SingleDateAndTimePickerDialog.Builder(mContext)
.title(mContext.getResources().getString(R.string.choose_time))
.displayListener(new SingleDateAndTimePickerDialog.DisplayListener() {
#Override
public void onDisplayed(SingleDateAndTimePicker picker) {
if(!isStart) {
date = mDate;
}
}
}).defaultDate(returnDate(date))
.listener(new SingleDateAndTimePickerDialog.Listener() {
#Override
public void onDateSelected(Date date) {
mDate = date;
if (isStart) {
updateShiftIn(mDate);
mshiftInText.setText(dateToString(mDate));
} else {
updateShiftOut(mDate);
mshiftOutText.setText(dateToString(mDate));
}
}
}).display();
return mDate;
}
public String dateToString(Date date)
{
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String string = df.format(date);
return string;
}
private void updateShiftIn(Date date) {
shiftIn = date;
}
private void updateShiftOut(Date date) {
shiftOut = date;
}
private Date returnDate(Date date)
{
if(date!=null)
{
return date;
}
else return mDate;
}
private void areYouSure(int i)
{
final String position = Integer.toString(i);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
Log.d(TAG, "onClick: isSure=true;");
SharedPrefs.getInstance(mContext).removeShift(position);
ShiftsFragment.updateUI();
case DialogInterface.BUTTON_NEGATIVE:
Log.d(TAG, "onClick: isSure= false");
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setMessage(mContext.getResources().getString(R.string.are_you_sure)).setPositiveButton(mContext.getResources().getString(R.string.confirm), dialogClickListener)
.setNegativeButton(mContext.getResources().getString(R.string.cancel), dialogClickListener).show();
}
private Shift newShift(Date start,Date stop)
{
int id = SharedPrefs.getInstance(mContext).getLength();
Shift shift = new Shift(dateToCalendar(start),dateToCalendar(stop),id);
return shift;
}
and this is the Fragment that has the RecyclerView
public class ShiftsFragment extends Fragment {
private Toolbar mToolbar;
private TimePicker timePicker1;
private List<Shift> shiftList = new ArrayList<>();
private RecyclerView recyclerView;
private RelativeLayout relativeLayout;
private RecyclerView.LayoutManager layoutManager;
private LinearLayout mShiftIn;
private LinearLayout mShiftOut;
private Context mContext;
private ShiftAdapter mAdapter;
private MenuItem mAdd;
private Menu optionsMenu;
private LinearLayout mShiftAddLL;
private SharedPreferences mPrefs;
private static FragmentManager mFragmentManager;
private static final String TAG = "ShiftsFragment";
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
Log.d(TAG,"Clicked");
final View view = inflater.inflate(R.layout.shifts_layout,container,false);
mToolbar = view.findViewById(R.id.topbar);
mToolbar.inflateMenu(R.menu.toolbarmenu);
mShiftAddLL = view.findViewById(R.id.add_shiftLayout);
mAdd = mToolbar.getMenu().getItem(0);
timePicker1 = (TimePicker) view.findViewById(R.id.timePicker);
mFragmentManager = getFragmentManager();
//TODO:Add a summary bar on the bottom.
//get the context
mContext = getContext();
recyclerView = (RecyclerView) view.findViewById(R.id.shift_list);
// Define a layout for RecyclerView
layoutManager = new GridLayoutManager(mContext,1);
recyclerView.setLayoutManager(layoutManager);
// Initialize a new Shift array
List<Shift> shiftList = initShifts();
Log.d(TAG,"shift array initiated");
// Initialize an array list from array
// Initialize a new instance of RecyclerView Adapter instance
mAdapter = new ShiftAdapter(mContext,shiftList);
// Set the adapter for RecyclerView
recyclerView.setAdapter(mAdapter);
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(true);
//Menu add button onClick
//Opens Add_Shift_Fragment
mAdd.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem menuItem) {
Fragment selectedFragment = new Add_Shift_Fragment();
getFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return false;
}
});
return view;
}
//Initializes the Shift list from SharedPreferences and returns it.
private List<Shift> initShifts() {
return SharedPrefs.getInstance(mContext).getShiftList();
}
public static void updateUI()
{
Fragment selectedFragment = new ShiftsFragment();
mFragmentManager.beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
}
}
Everytime i launch the ShiftsFragment there are some frame skips, and the scrolling is choppy and laggy.
Maybe my SharedPreferences handling is what is slowing things down?
public class SharedPrefs {
private static SharedPrefs mSharedPrefs;
private SharedPreferences mPrefs;
private SharedPreferences.Editor mPrefsEditor;
protected Context mContext;
public static final String ID = "shiftList";
private SharedPrefs(Context context) {
mContext = context;
mPrefs = context.getSharedPreferences(ID, Context.MODE_PRIVATE);
mPrefsEditor = mPrefs.edit();
}
public static SharedPrefs getInstance(Context context) {
if (mSharedPrefs == null) {
mSharedPrefs = new SharedPrefs(context.getApplicationContext());
}
return mSharedPrefs;
}
public void saveShiftList(List<Shift> shiftList) {
Gson gson = new Gson();
String json = gson.toJson(shiftList);
mPrefsEditor.putString(ID, json);
mPrefsEditor.apply();
}
public void addShift (Shift shift)
{
List<Shift> shiftList= getShiftList();
shiftList.add(shift);
saveShiftList(shiftList);
}
//Replaced the shift#id with shift
public void editShift(Shift shift,String id)
{
removeShift(id);
addShift(shift);
}
public void removeShift(String id) {
List<Shift> shiftList = getShiftList();
int pos = Integer.parseInt(id);
shiftList.remove(pos);
saveShiftList(shiftList);
}
public void removeShift(int id) {
List<Shift> shiftList = getShiftList();
shiftList.remove(id);
saveShiftList(shiftList);
}
public Shift getShift(int id) {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
Shift shift = shiftList.get(id);
return shift;
}
public List<Shift> getShiftList() {
Gson gson = new Gson();
List<Shift> shiftList;
String json = mPrefs.getString(ID, null);
Type type = new TypeToken<List<Shift>>() {
}.getType();
shiftList = gson.fromJson(json, type);
if (shiftList!=null) {
return shiftList;
} else{
shiftList = new ArrayList<>();
return shiftList;
}
}
public List<Shift> sortList(List<Shift> shiftList)
{
Collections.sort(shiftList, new Comparator<Shift>() {
public int compare(Shift shift1, Shift shift2) {
if (shift1.getShiftStart() == null || shift2.getShiftStart() == null)
return 0;
return shift1.getShiftStart().compareTo(shift2.getShiftStart());
}
});
return shiftList;
}
public int getLength()
{
return getShiftList().size();
}
}
I have only found this problem with image loading, not just Strings from Object from SharedPrefs.

Android recyclerView updata all list data still merge with old data

public RecyclerView.Adapter mAdapter;
public RecyclerView mMessagesView;
this is my list
public List<MessageList> Message_List = new ArrayList<MessageList>();
and this is my adapter
mAdapter = new MessageAdapter1(getApplicationContext(), Message_List);
mMessagesView = (RecyclerView) findViewById(R.id.messages);
mMessagesView.setLayoutManager(new LinearLayoutManager(this));
mMessagesView.setAdapter(mAdapter);
now i add some data on it
Message_List.add(messageList);
mAdapter.notifyItemInserted(Message_List.size() - 1);
its work without problems
now i want to change all Message_List data and show in in recyvlerView
i do this
public void swap(List<MessageList> datas){
Message_List.clear();
Message_List.addAll(datas);
mAdapter.notifyDataSetChanged();
}
here i replace all data in Message_List and notifyDataSetChanged now its shown new data of Message_List
empty Message_List show blank
but when i try add new item to list and notify adapter its shown to me some of old item i removed it from Message_List and in LOG i watch it no old data there
now this is image before update Message_List data
now change Message_List data and notify
like we see blank because there are no data on Message_List
now try add new item to Message_List and notify adapter
Message_List.add(balabala data);
mAdapter.notifyItemInserted(Message_List.size() - 1);
and result must be without old data
for more information this is my MessageList class
public class MessageList {
public static final int TYPE_MESSAGE_RIGHT = 0;
public static final int TYPE_MESSAGE_LEFT = 1;
public static final int TYPE_ACTION = 2;
public static final String TYPING = "typing";
private String message, thumbnailUrl;
private String date;
private int user_id;
private boolean status = false;
private String fname;
private String direction;
private ArrayList<String> messageList;
public MessageList() {
setMessageStatus(status);
}
public MessageList(String name, String thumbnailUrl, String date, String direction,
ArrayList<String> messageList, String fname, int user_id) {
this.message = name;
this.thumbnailUrl = thumbnailUrl;
this.date = date;
this.direction = direction;
this.messageList = messageList;
this.fname = fname;
this.user_id = user_id;
}
public String getMessage() {
return message;
}
public String getFname() {
return fname;
}
public void setMessage(String message) {
this.message = message;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
public String getDate() {
return date;
}
public boolean getMessageStatus() {
return status;
}
public void setMessageStatus(boolean status) {
this.status = status;
}
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
public void setDate(String date) {
this.date = date;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getDir() {
return direction;
}
public void setDir(String direction) {
this.direction = direction;
}
public ArrayList<String> getMessageList() {
return messageList;
}
public void setMessageList(ArrayList<String> messageList) {
this.messageList = messageList;
}
}
and this is my adapter
public class MessageAdapter1 extends RecyclerView.Adapter<MessageAdapter1.ViewHolder> {
private List<MessageList> mMessages;
private int[] mUsernameColors;
private Context context;
public MessageAdapter1(Context context, List<MessageList> messages) {
mMessages = messages;
this.context = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
int layout = -1;
int type = -1;
if(mMessages.get(viewType).getDir().equals("left")) type = 1;
else if(mMessages.get(viewType).getDir().equals("right")) type = 0;
else if(mMessages.get(viewType).getDir().equals("typing")) type = 2;
switch (type) {
case MessageList.TYPE_MESSAGE_RIGHT:
layout = R.layout.right_message;
break;
case MessageList.TYPE_MESSAGE_LEFT:
layout = R.layout.left_message;
break;
case MessageList.TYPE_ACTION:
layout = R.layout.message_left;
break;
}
View v = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
MessageList message = mMessages.get(position);
viewHolder.setGroupMessage(message);
}
#Override
public int getItemCount() {
return mMessages.size();
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ViewHolder extends RecyclerView.ViewHolder {
private LinearLayout groupMessage;
//private ImageView typing;
public ViewHolder(View itemView) {
super(itemView);
groupMessage = (LinearLayout)itemView.findViewById(R.id.messages);
}
public void setGroupMessage(MessageList m) {
if (null == groupMessage) return;
int i = 0;
if(m.getMessageStatus() == false){
m.setMessageStatus(true);
for (String message : m.getMessageList()) {
//TextView text = new TextView(activity);
TextView text = new MyTextView(context);
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
p.setMargins(0, 0, 0, 2);
if (m.getDir().equals("left")) {
text.setTextColor(Color.BLACK);
p.gravity = Gravity.LEFT;
if(m.getMessageList().size() == 1){
text.setBackgroundResource(R.drawable.message_left_default);
}
else if (i == 0) {
text.setBackgroundResource(R.drawable.message_left_first);
} else if (i + 1 == m.getMessageList().size()) {
text.setBackgroundResource(R.drawable.message_left_last);
} else {
text.setBackgroundResource(R.drawable.message_left);
}
} else{
p.gravity = Gravity.RIGHT;
text.setTextColor(Color.WHITE);
if(m.getMessageList().size() == 1){
text.setBackgroundResource(R.drawable.message_right_default);
}
else if (i == 0) {
text.setBackgroundResource(R.drawable.message_right_first);
} else if (i + 1 == m.getMessageList().size()) {
text.setBackgroundResource(R.drawable.message_right_last);
} else {
text.setBackgroundResource(R.drawable.message_right);
}
}
text.setLayoutParams(p);
text.setText(message);
text.setPadding(8, 8, 8, 8);
text.setTextSize(18f);
//text.setTextAppearance(context, android.R.style.TextAppearance_Large);
groupMessage.addView(text);
i++;
}
}
}
}
}
the problem is there is no connection between mMessages and Message_List. To achieve this, put swap() in the adapter class and call it from the activity or fragment.
public class MessageAdapter1 extends RecyclerView.Adapter<MessageAdapter1.ViewHolder> {
...
public void swap(List<MessageList> datas){
mMessages.clear();
mMessages.addAll(datas);
notifyDataSetChanged();
}
public void add(MessageList data){
mMessages.add(data);
notifyItemInserted(mMessages.size() - 1);
}
}
and from fragment or activity:
((MessageAdapter1) rv.getAdapter).add(data);
((MessageAdapter1) rv.getAdapter).swap(Message_List);

Categories

Resources