I am using RcyclerView adapter wich holding a chat messages list.
every time a message added to firebase I am using the 'onChildAdded' listener to update the adapter list. I also want to update certain messages by adding their background a changing color-animation.
the problem is I don't know how to access the position of specific messages in my adapter.
this is my chatListadapter:
class ChatListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<ChatMessage> msgList;
private static final int VIEW_TYPE_MESSAGE_LEFT = 1;
private static final int VIEW_TYPE_MESSAGE_RIGHT = 2;
private DataReferences DB;
ChatListAdapter(List<ChatMessage> msgList) {
this.msgList = msgList;
}
#Override
public int getItemCount() {
return msgList.size();
}
#Override
public int getItemViewType(int position) {
DB = DataReferences.getInstance();
ChatMessage msg = msgList.get(position);
if (!msg.uid.equals(DB.uid)) {
return VIEW_TYPE_MESSAGE_LEFT;
}
} else
return VIEW_TYPE_MESSAGE_RIGHT;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
if (viewType == VIEW_TYPE_MESSAGE_LEFT) {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_received, parent, false);
return new LeftViewHolder(view);
} else {
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_sent, parent, false);
return new RightViewHolder(view);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int
position) {
ChatMessage msg = msgList.get(position);
if (msg.critic)
switch (holder.getItemViewType()) {
case VIEW_TYPE_MESSAGE_LEFT:
((LeftViewHolder) holder).bind(msg);
break;
case VIEW_TYPE_MESSAGE_RIGHT:
((RightViewHolder) holder).bind(msg);
break;
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
private class LeftViewHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText, nameText;
public LeftViewHolder(View itemView) {
super(itemView);
timeText = (TextView) itemView.findViewById(R.id.text_message_time);
nameText = (TextView) itemView.findViewById(R.id.text_message_name);
messageText = (TextView)
itemView.findViewById(R.id.text_message_body);
}
void bind(ChatMessage message) {
messageText.setText(message.getMsg());
timeText.setText(message.getTime());
nameText.setText(message.UserName);
}
}
private class RightViewHolder extends RecyclerView.ViewHolder {
TextView messageText, timeText;
public RightViewHolder(View itemView) {
super(itemView);
timeText = (TextView) itemView.findViewById(R.id.text_message_time);
messageText = (TextView)
itemView.findViewById(R.id.text_message_body);
}
void bind(ChatMessage message) {
messageText.setText(message.getMsg());
timeText.setText(message.getTime());
}
}
}
I suggest you to used FirebaseRecyclerAdapter which come in FirebaseUI library (https://github.com/firebase/FirebaseUI-Android/blob/master/database/README.md). It makes handling data in RecyclerView become easier.
To make adapter update specific item. In populateViewHolder of FirebaseRecyclerAdapter you could do something like this (suppose you want to change message background if the message has been read)
override fun populateViewHolder(viewHolder: FieldViewHolder?, model: Message, position: Int) {
if(model.isRead) {
viewholder.updateBackground()
}
}
If you use plain RecyclerView it might need some effort to find specific position and update UI accordingly.
Hope it's help.
Related
I have a recycler view that shows transaction information. everything works good when its loaded but after scrolling a bit, contents of different rows gets mixed up.
Here is my code:
public TransactionAdapter.VHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = mInflater.inflate(R.layout.cell_transaction_history,parent,false);
VHolder holder = new VHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull TransactionAdapter.VHolder holder, int position) {
final Transaction transaction = transactionList.get(position);
holder.setData(transaction);
}
#Override
public int getItemCount() {
return transactionList.size();
}
private void setTransactionList(ArrayList<Transaction> transactions) {
this.transactionList = transactions;
}
And the ViewHolder:
private class VHolder extends RecyclerView.ViewHolder {
private AppCompatTextView schemeName;
private AppCompatTextView amount;
private AppCompatTextView bank;
private AppCompatTextView date;
private AppCompatTextView status;
VHolder(View itemView) {
super(itemView);
schemeName = itemView.findViewById(R.id.scheme_name);
amount = itemView.findViewById(R.id.amount);
bank = itemView.findViewById(R.id.bank);
date = itemView.findViewById(R.id.transaction_date);
status = itemView.findViewById(R.id.transaction_status);
}
private void setData(Transaction transaction) {
schemeName.setText(transaction.getSchemeName());
bank.setText(transaction.getBankName());
date.setText(transaction.getTranDate());
int amountValue = Integer.parseInt(transaction.getAmount());
if(amountValue < 0)
amount.setTextColor(getResources().getColor(R.color.color_status_cancelled));
else
amount.setTextColor(getResources().getColor(R.color.color_status_active));
amount.setText(abs(amountValue));
Drawable drawable = status.getCompoundDrawablesRelative()[0];
String st = transaction.getOrderStatus();
if(st.equalsIgnoreCase(TRAN_STATUS_PROCESSED)){
drawable.setTint(getResources().getColor(R.color.color_status_active));
status.setText(TRAN_STATUS_PROCESSED);
} else {
drawable.setTint(getResources().getColor(R.color.color_status_cancelled));
status.setText(TRAN_STATUS_REJECTED);
}
}
}
Tried setting
holder.setIsRecyclable(false);
but that is not an ideal solution I believe.
UPDATE:
recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
setContent(getUserTransactions());
And setContent() method:
private void setContent(ArrayList<Transaction> transactions) {
if(adapter == null) {
adapter = new TransactionAdapter(getLayoutInflater(),transactions);
recyclerView.setAdapter(adapter);
} else {
adapter.setTransactionList(transactions);
}
adapter.notifyDataSetChanged();
}
I have a RecyclerView defined in my android project. The Adapter for the RecyclerView is as follows
public class CustomAdapter1 extends RecyclerView.Adapter<CustomAdapter1.MyViewHolder> {
private Fragment1 myFrag;
private ArrayList<DataModel1> dataSet;
DBHandler db;
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView butAccept,butReject;
TextView nick,stat,tit,cat,desc,dt;
public CardView cardView;
public MyViewHolder(View itemView) {
super(itemView);
this.nick = (TextView) itemView.findViewById(R.id.nick);
this.stat = (TextView) itemView.findViewById(R.id.stat);
this.tit = (TextView) itemView.findViewById(R.id.tit);
this.cat = (TextView) itemView.findViewById(R.id.cat);
this.desc = (TextView) itemView.findViewById(R.id.desc);
this.dt = (TextView) itemView.findViewById(R.id.dt);
this.butAccept = (TextView)itemView.findViewById(R.id.accept_textview);
cardView = (CardView) itemView.findViewById(R.id.card_view);
cardView.setOnClickListener(this);
butAccept.setOnClickListener(this);
db = new DBHandler(itemView.getContext());
}
#Override
public void onClick(View v) {
if( v.getId() == butAccept.getId()){
String x = String.valueOf(dataSet.get(getAdapterPosition()).getMeetId());
myFrag.showToast(x);
}
}
}
public CustomAdapter1(ArrayList<DataModel1> data,Fragment1 frag) {
this.dataSet = data;
myFrag = frag;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent,int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.cardfrag1, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(view);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder,final int listPosition) {
TextView nick = holder.nick;
TextView stat = holder.stat;
TextView tit = holder.tit;
TextView cat = holder.cat;
TextView desc = holder.desc;
TextView dt= holder.dt;
nick.setText(dataSet.get(listPosition).getNick());
stat.setText(dataSet.get(listPosition).getStat());
tit.setText(dataSet.get(listPosition).getTit());
cat.setText(dataSet.get(listPosition).getCat());
desc.setText(dataSet.get(listPosition).getDesc());
dt.setText(dataSet.get(listPosition).getDt());
}
#Override
public int getItemCount() {
return dataSet.size();
}
}
The final TextView butAccept has dynamic values.I have an internal DB that has the column Status. When the value of the Status is 1 I need to change the text that is being displayed in the TextView butAccept.
How should I do this? Should I write a function in my CustomAdapter, or in the fragment in which I am using the adapter?
In my Fragment I have a function :
private void checkTheAcceptStatus(int x){
int status = db.getMeetingStatus(x);
Toast.makeText(getActivity(),String.valueOf(status),Toast.LENGTH_SHORT).show();
if(status == 1){
}
}
This function is being called everytime a new item is added to the adapter. The internal DB is being queried correctly and if the value of Status is being returned. If the value is 1 what should I do?
I saw this question, but this is unclear and I was unable to come to any conclusion from this.
If I understood correctly every row in your list has this accept button. So in your onBindViewHolder() you cant set the buttons text depending on the state of your status variable. When you detect changes in your db you can use the various notify methods provided depending on your needs: notifyItemChanged(...), notifyItemRangeChanged(...), notifyItemAdded(...), notifyItemRemoved(...) etc. Your onBindViewHolder should look something like this:
#Override
public void onBindViewHolder(final ViewHolder vh, int position) {
if(dataSet.get(position).getStatus() == 1){
vh.butAccept.setText("Your status 1 case text here");
} else {
vh.butAccept.setText("Your status not 1 case text here");
}
}
Also you can just use notifyDataSetChanged() if you want to refresh the whole list, but the methods above are more efficient.
Unable to add second child in Recyclerview I am passing two different arrays to RecyclerAdapter to display two child layout with different data and views.Is there any solution to add different child layout using same header layout.I added horizontal Recyclerview in vertical Recyclerview and I want to display details like I attached the image
private void setupRecyclerView(RecyclerView recyclerView) {
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
RecyclerAdapter recyclerAdapter = new RecyclerAdapter();
int[] images = new int[]{
R.drawable.finance,
R.drawable.business,
R.drawable.financejob,
R.drawable.ecomchallenges
};
ArrayList<ChildView> childViews = new ArrayList<>();
childViews.add(new ChildView(images[0], "The \"Best\" Startup Pitch Deck - How To Raise Venture Capital", "$100"));
childViews.add(new ChildView(images[1], "An Entire MBA in 1 Course:Award Winning Business School Prof", "$100"));
childViews.add(new ChildView(images[2], "What Finance Job is for You? Explanation of 14 Finance Roles", "$100"));
childViews.add(new ChildView(images[3], "Learn To Build Beautiful HTML5 And CSS3 Websites In 1 Month", "$100"));
int[] courseImage = new int[] {
R.drawable.php,
R.drawable.development,
R.drawable.web,
R.drawable.java
};
ArrayList<CourseByType> courseByTypes = new ArrayList<>();
courseByTypes.add(new CourseByType("Technology", courseImage[0]));
courseByTypes.add(new CourseByType("Business", courseImage[1]));
courseByTypes.add(new CourseByType("Photography", courseImage[2]));
courseByTypes.add(new CourseByType("Development", courseImage[3]));
Log.d("","Above adapter");
recyclerAdapter.addItem(new GroupView("Business", childViews));
Log.d("","Below Child");
recyclerAdapter.addCourseByType(new CourseByHeader("Technology", courseByTypes));
Log.d("","Below Course");
recyclerView.setAdapter(recyclerAdapter);
}
This is the main fragment where I set the values to two different
arraylist ArrayList<ChildView> childViews = new ArrayList<>()
and
ArrayList<CourseByType> courseByTypes = new ArrayList<>()
Values of child views are passing properly but CourseByType values are not passing.This is the adapter class for this fragment class.
RecyclerAdapter.java
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
ArrayList<PassValues> containerArrayList;
ArrayList<GroupView> groupViews;
ArrayList<CourseByHeader>courseByHeaders;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
View view = LayoutInflater.from(context).inflate(R.layout.group_title, parent, false);
return new ViewHolder(view);
}
public RecyclerAdapter(){
containerArrayList = new ArrayList<>();
groupViews = new ArrayList<>();
courseByHeaders = new ArrayList<>();
}
public void addContainer(PassValues container){
containerArrayList.add(container);
}
public void addItem(GroupView groupView){
Log.d("","Inside Group method");
groupViews.add(groupView);
}
public void addCourseByType(CourseByHeader courseByHeader){
Log.d("","Inside Course method");
courseByHeaders.add(courseByHeader);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Log.d("", "Pass Values out of IF" + position);
ChildViewAdapter childViewAdapter = new ChildViewAdapter();
if(position == 0){
GroupView groupView = groupViews.get(position);
holder.title.setText(groupView.getTitle());
Log.d("", "Passing Values" + groupView.getTitle());
holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.recyclerView.getContext(), LinearLayoutManager.HORIZONTAL, false));
holder.recyclerView.setOnFlingListener(null);
childViewAdapter.addChild(groupView.getChildViewList());
holder.recyclerView.setAdapter(childViewAdapter);
}
if (position == 1) {
CourseByHeader courseByHeader = courseByHeaders.get(position);
holder.title.setText(courseByHeader.getTitle());
Log.d("", "Passing Values" + courseByHeader.getTitle());
holder.recyclerView.setLayoutManager(new LinearLayoutManager(holder.recyclerView.getContext(), LinearLayoutManager.HORIZONTAL, false));
holder.recyclerView.setOnFlingListener(null);
childViewAdapter.addCourse(courseByHeader.getCourseByTypes());
holder.recyclerView.setAdapter(childViewAdapter);
}
}
#Override
public int getItemCount() {
if(getItemViewType(0) == TYPE_HEADER)
return groupViews.size() ;
if (getItemViewType(1) == TYPE_ITEM)
return courseByHeaders.size();
else return -1;
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView title;
RecyclerView recyclerView;
public ViewHolder(View itemView) {
super(itemView);
title = (TextView)itemView.findViewById(R.id.course_title);
recyclerView = (RecyclerView)itemView.findViewById(R.id.group_recycler);
}
}
}
This RecyclerAdapter contains one RecyclerView in that first row has one image and 3 textviews and 2nd row has 1 ImageView and 1 TextView. At position first,one image and 3 textviews are shown but it's not going on 2nd view
This is the view I getting after run on emulator.
This are two child for RecyclerViews
ChildView.java
public class ChildView {
int image;
String course, price;
public ChildView(int image, String course, String price) {
this.image = image;
this.course = course;
this.price = price;
}
public int getImage() {
return image;
}
public String getCourse() {
return course;
}
public String getPrice() {
return price;
}
}
CourseByType.java
public class CourseByType {
String courseName;
int courseImage;
public CourseByType(String courseName, int courseImage) {
this.courseName = courseName;
this.courseImage = courseImage;
}
public String getCourseName() {
return courseName;
}
public int getCourseImage() {
return courseImage;
}
}
CourseByHeader.java
public class CourseByHeader {
String title;
ArrayList<CourseByType> courseByTypes;
public CourseByHeader(String title, ArrayList<CourseByType> courseByTypes) {
this.title = title;
this.courseByTypes = courseByTypes;
}
public String getTitle() {
return title;
}
public ArrayList<CourseByType> getCourseByTypes() {
return courseByTypes;
}
}
GroupView.java
public class GroupView {
String title;
ArrayList<ChildView> childViewList;
String courseBy;
ArrayList<CourseByType> courseByTypes;
public GroupView(String title, ArrayList<ChildView> childViewList) {
this.title = title;
this.childViewList = childViewList;
}
public String getTitle() {
return title;
}
public ArrayList<ChildView> getChildViewList() {
return childViewList;
}
}
Groupview and CouseByType class have title and child list for recycleradapter
ChildViewAdapter.java
public class ChildViewAdapter extends RecyclerView.Adapter {
ArrayList<ChildView> childViewList;
ArrayList<CourseByType> courseByTypes;
private static final int TYPE_HEADER = 0;
private static final int TYPE_ITEM = 1;
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(View itemView) {
super(itemView);
}
}
public class GroupHolder extends ViewHolder {
public ImageView iamView;
public TextView course, price;
public GroupHolder(View itemView) {
super(itemView);
iamView = (ImageView) itemView.findViewById(R.id.course_image);
course = (TextView) itemView.findViewById(R.id.course_by);
price = (TextView) itemView.findViewById(R.id.price);
}
}
public void addCourse(ArrayList<CourseByType> courseByType){
courseByTypes = courseByType;
}
public void addChild(ArrayList<ChildView> childView){
childViewList = childView;
}
public class Course extends ViewHolder {
public ImageView courseTypeImage;
public TextView courseType;
public Course(View itemView) {
super(itemView);
courseTypeImage = (ImageView)itemView.findViewById(R.id.course_image);
courseType = (TextView)itemView.findViewById(R.id.course_name_course);
}
}
public ChildViewAdapter() {
childViewList = new ArrayList<>();
courseByTypes = new ArrayList<>();
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
Context context = parent.getContext();
RecyclerView.ViewHolder vh = null;
View v;
if(viewType == TYPE_HEADER){
v = LayoutInflater.from(context).inflate(R.layout.recycler_item, parent, false);
return new GroupHolder(v);
}if(viewType == TYPE_ITEM){
v = LayoutInflater.from(context).inflate(R.layout.type_of_courses, parent, false);
return new Course(v);
}
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if(holder instanceof GroupHolder){
Log.d("","instance of Group Holder");
ChildView childView = childViewList.get(position);
((GroupHolder)holder).iamView.setImageResource(childView.getImage());
((GroupHolder)holder).course.setText(childView.getCourse());
((GroupHolder)holder).price.setText(childView.getPrice());
return;
}
if(holder instanceof Course){
Log.d("","instance of Course ");
CourseByType courseByType = courseByTypes.get(position);
((Course)holder).courseTypeImage.setImageResource(courseByType.getCourseImage());
((Course)holder).courseType.setText(courseByType.getCourseName());
return;
}
}
#Override
public int getItemCount() {
int size;
if(childViewList.size()>0){
return size = childViewList.size();
}else return size = courseByTypes.size();
}
#Override
public int getItemViewType(int position) {
if(childViewList.size() != 0 && childViewList.size()>0){
return TYPE_HEADER;
}else return TYPE_ITEM;
}
}
This childview adapter has two view types first is one image and 3 text and second view type contain one image and one text.When I pass values from fragment only first view type get displayed and second view type not gets value from fragment.
To show multiple different views in a recyclerview, you have to override getItemViewType() in the recyclerview adapter.
//getItemViewType enables dynamic viewholder creation
#Override
public int getItemViewType(int position) {
//you will need to add a integer with variable name viewTypeCode
//for view1 set viewTypeCode = 100 and for view2 set viewTypeCode = 200
viewTypeCode = itemList.get(position).getViewTypeCode();
return viewTypeCode;
}
This is how the onCreateViewHolder will be different for multiple viewtypes. You will have to modify yours like this
#Override
public FeedViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case 100: return new FeedViewHolder(layoutInflater.inflate(R.layout.v1, parent, false),100);
case 200: return new FeedViewHolder(layoutInflater.inflate(R.layout.v2, parent, false),200);
}
return null;
}
OnBindViewHolder will be similarly modified
#Override
public void onBindViewHolder(final FeedViewHolder holder, int position) {
viewTypeCode = itemList.get(position).getViewTypeCode();
switch ( viewTypeCode) {
case 100:
//your code for v1
case 200:
//your code for v2
}
}
Similarly the ViewHolder class is modified
class FeedViewHolder extends RecyclerView.ViewHolder{
//declare variables here
public FeedViewHolder(View v, int viewType) {
super(v);
switch (viewType) {
//instead of itemView.findViewById you will have to use v.findViewById
case 100:
//your code for v1
case 200:
//your code for v2
}
}
For further reference refer to this SO answer
Don't pass two separate list.Make a custom class like this-
class MyClass {
int viewTypeCode;
CustomClass1 c1;
CustomClass2 c2;
//add the setter getter
}
In your activity while preparing the data.
List<MyClass> itemList = new ArrayList<>();
//put whatever logic you need to make the order of the list
//if CustomClass1 object is put then setViewTypeCode(100), setCustomClass2 = null
//if CustomClass2 object is put then setViewTypeCode(200), setCustomClass1 = null
After data is built, then send this to the adapter.
I have a RecyclerView which shows list of items sorted in descending order that works fine when I initially launch the screen, but when I add some more items to the existing list and setting it to the adapter with notifyDataSetChanged() method the existing list gets sorted in ascending order and the new items get added at the bottom of the view.
below is adapter
public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {
private List<Cinema> lists;
private int savedItems;
public RecycleAdapter(List<Cinema> cinemas, int savedItems) {
this.lists = cinemas;
this.savedItems = savedItems;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView cinemaTitle;
public TextView cinemaDescription;
public TextView cinemaDate;
public LinearLayout newLayout;
public ViewHolder(View view) {
super(view);
cinemaTitle = (TextView) view.findViewById(R.id.cinema_title);
cinemaDescription = (TextView) view.findViewById(R.id.description_text);
cinemaDate = (TextView) view.findViewById(R.id.cinema_date);
newLayout = (LinearLayout) view.findViewById(R.id.new_cinema_layout);
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_cinema, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Cinema cinema = cinemas.get(position);
if (cinema.getId() > savedItems) {
holder.newLayout.setVisibility(View.VISIBLE);
} else {
holder.newLayout.setVisibility(View.INVISIBLE);
}
String title = cinema.getMessage().trim();
String description = cinema.getDescription().trim();
String date = cinema.getPublishedDate().trim();
holder.cinemaTitle.setText(title);
holder.cinemaDescription.setText(description);
holder.cinemaDate.setText(date);
}
public void setCineams(List<Cinema> cinemas) {
this.cinemas = cinemas;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
return cinemas.size();
}
}
and the method which updates the list from Fragment is given below:
#Override
public void onCinemaUpdated() {
cinemas = firebaseHelper.getAllCinemas();
//Method which sorts the lists in descending order after adding new items into it
sortCinemas();
if (recycleAdapterAdapter != null) {
recycleAdapterAdapter.setCineams(cinemas);
}
}
I am not sure why am I getting this behaviour. Can anyone clarify on this?
Change your constructor and setCinemas method code to : Let me know if it helps..
public RecycleAdapter(List<Cinema> cinemas, int savedItems) {
this.lists = cinemas;
this.savedItems = savedItems;
}
public void setCineams(List<Cinema> cinemas) {
this.lists = cinemas;
notifyDataSetChanged();
}
I am using card view and recycler view with footer.
It is survey form with textview showing questions and ratingbar.
There will be more than one questions and footer will have textarea and submit button.
I tried to get the rating bar's rating on click of submit button but I am getting the rating of the last cardview of the recyclerview.
Below is the code I am using to get the ratings.
submitResponse() method is called on click of submit button and I am writing the code to get the rating's of all the cardview in it.
public class SurveyDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final int FOOTER_VIEW = 1;
static List<SurveyQuestions> surveyQuestionses= new ArrayList<>();
public static Activity ctx;
public static ScheduleData scheduleData;
public static SurveyDetailsViewHolder vh;
public SurveyDetailsAdapter(List<SurveyQuestions> surveyQuestionses,Activity ctx,ScheduleData scheduleData) {
this.surveyQuestionses = surveyQuestionses;
this.ctx=ctx;
this.scheduleData=scheduleData;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
if (viewType == FOOTER_VIEW) {
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_footer, parent, false);
FooterViewHolder vh = new FooterViewHolder(v);
return vh;
}
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.survey_details_view_layout, parent, false);
SurveyDetailsViewHolder pvh = new SurveyDetailsViewHolder(v);
return pvh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
// holder.time.setText(String.valueOf(scheduleData.get(position).starttime+"-"+String.valueOf(scheduleData.get(position).endtime)));
// holder.title.setText(String.valueOf(scheduleData.get(position).title));
// holder.date.setText(String.valueOf(scheduleData.get(position).date));
try {
if (holder instanceof SurveyDetailsViewHolder) {
vh = (SurveyDetailsViewHolder) holder;
vh.question.setText(surveyQuestionses.get(position).question);
// vh.bindView(position);
} else if (holder instanceof FooterViewHolder) {
FooterViewHolder vh = (FooterViewHolder) holder;
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public int getItemCount() {
if (surveyQuestionses == null) {
return 0;
}
if (surveyQuestionses.size() == 0) {
return 1;
}
return surveyQuestionses.size()+1;
}
// Now define getItemViewType of your own.
#Override
public int getItemViewType(int position) {
if (position ==surveyQuestionses.size()) {
// This is where we'll add footer.
return FOOTER_VIEW;
}
return super.getItemViewType(position);
}
#Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
}
public class FooterViewHolder extends RecyclerView.ViewHolder {
EditText comments;
MainActivity mainActivity = (MainActivity) ctx;
public FooterViewHolder(final View itemView) {
super(itemView);
itemView.findViewById(R.id.submit).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Do whatever you want on clicking the item
submitResponse();
Toast.makeText(mainActivity.getApplicationContext(),"Thank you.", Toast.LENGTH_SHORT).show();
mainActivity.switchContent(Surveys.FRAGMENT_TAG);
}
});
}
public void submitResponse(){
comments=(EditText)itemView.findViewById(R.id.comments);
List<String> rat= new ArrayList<String>();
for(int i=0;i<surveyQuestionses.size();i++){
rat.add(String.valueOf(SurveyDetailsViewHolder.ratingBar.getRating()));
}
for(int j=0;j<rat.size();j++){
Toast.makeText(mainActivity.getApplicationContext(),rat.get(0).toString()+rat.get(1).toString()+rat.get(2).toString(), Toast.LENGTH_SHORT).show();
}
}
}
// So you're done with adding a footer and its action on onClick.
// Now set the default ViewHolder for NormalViewHolder
public static class SurveyDetailsViewHolder extends RecyclerView.ViewHolder {
public static CardView cv;
TextView question;
public static RatingBar ratingBar;
SurveyDetailsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.card_view_layout);
question = (TextView) itemView.findViewById(R.id.que1);
ratingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
}
}
}
You have SurveyQuestion POJO. Add your POJO new field , you can call it rating
public class SurveyQuestion {
public float rating = 0.0f; //this will be default value, if user has not rate, this value will be passed
// Your other variabes, constructors etc.
}
Then, you need to listen your rating bar changes on your RecyclerView Adapter
public static class SurveyDetailsViewHolder extends RecyclerView.ViewHolder {
public static CardView cv;
TextView question;
public static RatingBar ratingBar;
SurveyDetailsViewHolder(View itemView) {
super(itemView);
cv = (CardView) itemView.findViewById(R.id.card_view_layout);
question = (TextView) itemView.findViewById(R.id.que1);
ratingBar = (RatingBar) itemView.findViewById(R.id.ratingBar);
ratingBar .setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
#Override
public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
surveyQuestionses.get(getPosition()).rating = ratingBar.getRating();
}
});
}
}
Lastly on your submitResponse() method you can access your ratings from your surveyQuestionses list.
public void submitResponse(){
comments=(EditText)itemView.findViewById(R.id.comments);
List<String> rat= new ArrayList<String>();
for(int i=0;i<surveyQuestionses.size();i++){
rat.add(String.valueOf(surveyQuestionses.rating));
}
}