I know there is no setText() function for Spinner, but I still don't know how to replace it with a more suitable method.
This error pointed out by Android Studio comes from the onBindViewHolder method.
// error: cannot find symbol method setText(String)
holder.spinnerCategory_book.setText(v_book.getCategory_book());
public class BookAdapter extends RecyclerView.Adapter<BookAdapter.ViewHolder> {
List<Book> books;
Context context;
DatabaseHelperClass bd;
public BookAdapter(List<Adapter> books, Context context) {
this.books = books;
this.context = context;
bd = new DatabaseHelperClass(context);
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.activity_view_books,parent,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, final int position) {
final Book v_book = books.get(position);
holder.textId_book.setText(Integer.toString(v_book.getId_book()));
holder.editTitle_book.setText(v_book.getTitle_book());
holder.editAuthor_book.setText(v_book.getAuthor_book());
holder.spinnerCategory_book.setText(v_book.getCategory_book()); // Line error
holder.editPublisher_book.setText(v_book.getPublisher_book());
holder.editPages_book.setText(Integer.toString(v_book.getPages_book()));
holder.editYear_publication.setText(Integer.toString(v_book.getYear_publication()));
holder.button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String title_book = holder.holder.editTitle_book.getText().toString();
String author_book = holder.editAuthor_book.getText().toString();
String category_book = holder.spinnerCategory_book.getSelectedItem().toString();
String publisher_book = holder.editPublisher_book.getText().toString();
int pages_book = Integer.parseInt(holder.editPages_book.getText().toString());
int year_publication = Integer.parseInt(holder.editYear_publication.getText().toString());
bd.UpdateBook(new Book(v_books.getId_book(),title_book,author_book,
category_book,publisher_book,pages_book,year_publication));
notifyDataSetChanged();
((Activity) context).finish();
context.startActivity(((Activity) context).getIntent());
}
});
holder.button_delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
bd.DeleteBook(v_book.getId_book());
books.remove(position);
notifyDataSetChanged();
}
});
}
#Override
public int getItemCount() {
return books.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
Button button_update, button_delete;
TextView textId_book;
EditText editTitle_book, editAuthor_book, editPublisher_book, editPages_book, editYear_publication;
Spinner spinnerCategory_book;
public ViewHolder(#NonNull View itemView) {
super(itemView);
textId_book = itemView.findViewById(R.id.textId_book);
editTitle_book = findViewById(R.id.editTitle_book);
editAuthor_book = findViewById(R.id.editAuthor_book);
editPublisher_book = findViewById(R.id.editPublisher_book);
editPages_book = findViewById(R.id.editPages_book);
editYear_publication = findViewById(R.id.editYear_publication);
spinnerCategory_book = findViewById(R.id.spinnerspinnerCategory_book);
button_update = itemView.findViewById(R.id.button_update_book);
button_delete = itemView.findViewById(R.id.button_delete_book);
}
}
}
I know there is no setText() function for Spinner, but I still don't know how to replace it with a more suitable method.
1 - Go to the documentation for Spinner.
2 - Scroll down to the section that lists the public methods to see what's available to you, specifically anything starting with "set". If you don't find anything useful, then look at the inherited methods to see what you get from the base class(es).
3 - Discover setSelection which "Sets the currently selected item." based on it's position within the list of items and sounds like what you're trying to do.
4 - Update your code to work with the API you have, not the API you want.
final Book v_book = books.get(position);
// holder.spinnerCategory_book.setText(v_book.getCategory_book()); // Line error
holder.spinnerCategory_book.setSelection(position);
Related
I am working on an application where i have list of items in recyclerview on items i have a hear icon as wishlist the problem is when i click on the first item the last item automatically selected when i select the second item the second last got selected automatically. I dont know why this is happening?? please guide me
My RecyclerView Adapter
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.name.setText(datalist.get(position).getName());
holder.email.setText(datalist.get(position).getEmail());
holder.desc.setText(datalist.get(position).getDesc());
holder.book.setText(datalist.get(position).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(position).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(position);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int pos = holder.getBindingAdapterPosition();
if(compoundButton.isChecked())
{
Toast.makeText(context, "item added to wishlist" + pos , Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(context, "item removed to wishlist", Toast.LENGTH_SHORT).show();
}
}
});
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}
i click on the first heart icon
the last one is automatically clicked
Why this happening? Because when you scroll recyclerview remove hidden items automatically. For ex: 0 will be remove when scroll down and 1 item will be 0, 2 item will be 1 and 3->2,4->3 like this. There are 2 ways fix this error:
1) Simple way, but this method freeze your app when data is big:
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
holder.setIsRecyclable(false);
}
2) If you want you use second method you must add unique_id to your arraylist each item:
public class RecyclerviewAdapter extends RecyclerView.Adapter<RecyclerviewAdapter.Viewholder> {
ArrayList<RecyclerviewModel> datalist;
Context context;
private ArrayList<String> checkedItems=new ArrayList<>();
public RecyclerviewAdapter(ArrayList<RecyclerviewModel> datalist, Context context) {
this.datalist = datalist;
this.context = context;
}
#NonNull
#Override
public Viewholder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View viewholder = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_item, parent , false);
return new Viewholder(viewholder);
}
#Override
public void onBindViewHolder(#NonNull Viewholder holder, int position)
{
int pos=holder.getAdapterPosition();
holder.name.setText(datalist.get(pos).getName());
holder.email.setText(datalist.get(pos).getEmail());
holder.desc.setText(datalist.get(pos).getDesc());
holder.book.setText(datalist.get(pos).getBook());
//code for setting image-slider on home
holder.sliderAdapterExample = new SliderAdapterExample(context.getApplicationContext(), datalist.get(pos).getImages());
holder.imageSlider.setSliderAdapter(holder.sliderAdapterExample);
final RecyclerviewModel datawish = datalist.get(pos);
String wishName = datawish.getName();
String wishEmail = datawish.getEmail();
holder.wishlist.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
checkedItems.add(datalist.get(pos).getUniqueId());
} else {
checkedItems.remove(datalist.get(pos).getUniqueId());
}
}
});
// Check your selection here
if(checkedItems.contains(datalist.get(pos).getUniqueId())){
holder.wishlist.setChecked(true);
} else {
holder.wishlist.setChecked(false);
}
}
#Override
public int getItemCount() {
return datalist.size();
}
public class Viewholder extends RecyclerView.ViewHolder{
TextView name, email, desc, book;
SliderView imageSlider;
SliderAdapterExample sliderAdapterExample;
CheckBox wishlist;
public Viewholder(#NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
email = itemView.findViewById(R.id.text_email);
desc = itemView.findViewById(R.id.text_desc);
book = itemView.findViewById(R.id.text_book);
wishlist = itemView.findViewById(R.id.wishlist_checkbox);
imageSlider = itemView.findViewById(R.id.imageView3);
}
}
}
When you call your Adapter in your Fragment or Activity, add this line before setAdapter()
recyclerView.setItemViewCacheSize(mData.size());
I am doing some kind of Medication Reminder App for our school and I am trying to create an Expandable RecyclerView based on a video I watch and practically followed step by step. Did everything practically the same but we created a Database instead of just fixed values. The problem I have is that after initializing in the Main Activity, my list value is always Null and that my adapter is returning a NULL. What am I doing wrong?
Here is my code.
MediReminders.java
I've decided to remove this because its just a bunch of getters and setters
MedAdapters.java
public class MedAdapters extends RecyclerView.Adapter<MedAdapters.MediRemindersVH> {
List<MediReminders> MedList;
public MedAdapters(List<MediReminders> MedList) {
this.MedList = MedList;
}
#NonNull
#Override
public MedAdapters.MediRemindersVH onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row,parent,false);
return new MediRemindersVH(view);
}
#Override
public void onBindViewHolder(#NonNull MedAdapters.MediRemindersVH holder, int position) {
MediReminders mediReminders = MedList.get(position);
holder.med_nameTxt.setText(mediReminders.getMed_name());
holder.med_typeTxt.setText(mediReminders.getMed_type());
holder.fromdatedetailTxt.setText(mediReminders.getFromDatedetail());
holder.todatedetailTxt.setText(mediReminders.getToDatedetail());
holder.timedetailTxt.setText(mediReminders.getTimedetail());
holder.whendetailTxt.setText(mediReminders.getWhendetail());
holder.notesdetailTxt.setText(mediReminders.getNotesdetail());
boolean isExpandable = MedList.get(position).isExpandable();
holder.expandableLayout.setVisibility(isExpandable ? View.VISIBLE : View.GONE);
}
#Override
public int getItemCount() {
return MedList.size();
}
public class MediRemindersVH extends RecyclerView.ViewHolder {
TextView med_nameTxt, med_typeTxt, fromdatedetailTxt, todatedetailTxt, timedetailTxt, whendetailTxt, notesdetailTxt;
LinearLayout linearLayout;
RelativeLayout expandableLayout;
public MediRemindersVH(#NonNull View itemView) {
super(itemView);
med_nameTxt = itemView.findViewById(R.id.medname);
med_typeTxt = itemView.findViewById(R.id.auto_complete_txt);
fromdatedetailTxt = itemView.findViewById(R.id.fromdate);
todatedetailTxt = itemView.findViewById(R.id.todate);
timedetailTxt = itemView.findViewById(R.id.datetime);
whendetailTxt = itemView.findViewById(R.id.radioGroup);
notesdetailTxt = itemView.findViewById(R.id.notes);
linearLayout = itemView.findViewById(R.id.linear_layout);
expandableLayout = itemView.findViewById(R.id.expandable_layout);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
MediReminders mediReminders = MedList.get(getAdapterPosition());
mediReminders.setExpandable(!mediReminders.isExpandable());
notifyItemChanged(getAdapterPosition());
}
});
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
List<MediReminders> MedList;
MedAdapters adapter = new MedAdapters(MedList);
ImageButton addNewButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
recyclerView = findViewById(R.id.MedList);
setContentView(R.layout.activity_main_list);
initData();
setRecyclerView();
}
private void setRecyclerView () {
//problem is specifically this one...
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
}
private void initData () {
MedList = new ArrayList<>();
MedList.add(new MediReminders("Paracetamol", "Tablet", "Apr 26, 2022", "May 9,2022", "6:30 PM", "Before Meal", "Take in water first"));
}
}
First, Try to check your application with Fixed hard coded values.
If it's working fine.
Second, run and check your database query on some dbms tool.
I have a boolean in my onBindViewHolder which decides whether a button is clickable or not.
In the constructor I set this value to false, later when the user unlocks something I want to set it to true with a setter.
Here is my RecyclerViewAdapter.java:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
private ArrayList<Items> items;
Context mContext;
private boolean unlocked;
public RecyclerViewAdapter(Context context, ArrayList<Items> items, boolean unlocked) {
mContext = context;
this.items = items;
this.unlocked = tabUnlocked;
}
public void setUnlocked(boolean unlocked) {
this.unlocked = unlocked;
this.notifyDataSetChanged();
}
#NonNull
#Override
public RecyclerViewAdapter.iewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
v.setLayoutParams(lp);
return new RecyclerViewAdapter.ViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull final RecyclerViewAdapter.ViewHolder holder, int position) {
final Items currentItem = items.get(position);
final String name = currentItem.getName();
holder.itemTextView.setText(name);
holder.itemTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (unlocked) {
//do something
}
}
});
}
#Override
public int getItemCount() {
return item.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView itemTextView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
itemTextView = itemView.findViewById(R.id.textViewItem);
}
}
}
And here is how I call the Setter to change it:
I make the RecyclerView public:
public RecyclerViewAdapter adapter;
Then I create an instance in my onCreate:
recyclerView = rootView.findViewById(R.id.recyclerView);
adapter = new RecyclerViewAdapter(items);
recyclerView.setAdapter(adapter);
And when the user unlocks a certain thing I call this method of the current Class:
public void unlockTab() {
adapter.setUnlocked(true);
}
When I log the boolean inside of that setter it tells me it got changed.
But when I log the boolean inside the onBindViewHolder it still remains false.
Why is the setter method not setting the boolean to true in the whole RecyclerViewAdapter.java class?
Hope someone can help me!
EDIT
I already tried adding "this.notifyDataSetChanged();" to the Setter Method (Thanks to #a_local_nobody)
Adapters are responsible for changes to recyclerviews. but if you don't tell them something changed, they won't know to do so.
call notifyDataSetChanged();
public void unlockTab() {
adapter.setUnlocked(true);
adapter.notifyDataSetChanged();
}
what does it do ?
It tells your recyclerview to bind all the data again, so then your changes will apply
I built a simple quiz app with sqlite database
There is some quiz headers and into this quiz headers we have some questions that show by recycler view. All questions have one question title and 4 answers and one correct answer. user chooses the radio button answers and after that click on confirm button that is located as item at the bottom of recycler view.
I can catch the correct answer with a simple way and send it to the activity with an interface. But i want to show the correct and wrong answers with changing the radio buttons color but I can't create another method and change the view holder items because I can't access to the view holders outside of 'onBindViewHolder' method . I can handle this with another adapter . I mean I can create a fake adapter that just show answers . Is it a right way ?
This is my code. It's a little messy. Sorry about that
public class QuestionRecyclerAdapter extends RecyclerView.Adapter<QuestionRecyclerAdapter.ViewHolder> {
private Context context;
private List<QuestionHolder> questionHolders;
private OnQuestionAnswerSelect onQuestionAnswerSelect;
private OnConfirmButtonClicked onConfirmButtonClicked;
public QuestionRecyclerAdapter(Context context, List<QuestionHolder> questionHolders) {
this.context = context;
this.questionHolders = questionHolders;
}
public void setOnQuestionAnswerSelect(OnQuestionAnswerSelect onQuestionAnswerSelect) {
this.onQuestionAnswerSelect = onQuestionAnswerSelect;
}
public void setOnConfirmButtonClicked(OnConfirmButtonClicked onConfirmButtonClicked){
this.onConfirmButtonClicked = onConfirmButtonClicked;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView;
if (viewType == R.layout.question_item)
itemView = LayoutInflater.from(context).inflate(R.layout.question_item, parent, false);
else
itemView = LayoutInflater.from(context).inflate(R.layout.question_recycler_confirm_button, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
if (position != questionHolders.size()) {
QuestionModel currentModel = questionHolders.get(position).getQuestionModel();
holder.txtQuestion.setText(currentModel.getTitle());
holder.rBtnAnswer1.setText(currentModel.getOption1());
holder.rBtnAnswer2.setText(currentModel.getOption2());
holder.rBtnAnswer3.setText(currentModel.getOption3());
holder.rBtnAnswer4.setText(currentModel.getOption4());
if (onQuestionAnswerSelect != null) {
holder.questionRadioGroup.setOnCheckedChangeListener((v, i) -> {
RadioButton rBtnSelected = holder.questionRadioGroup.findViewById(holder.questionRadioGroup.getCheckedRadioButtonId());
int selectedRadioIndex = holder.questionRadioGroup.indexOfChild(rBtnSelected) + 1;
if (selectedRadioIndex == questionHolders.get(position).getQuestionModel().getCorrectNumber()) {
onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), true);
} else {
onQuestionAnswerSelect.onAnswerSelected(questionHolders.get(position).get_id(), false);
}
});
}
}else {
holder.btnConfirm.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (onConfirmButtonClicked != null)
onConfirmButtonClicked.onConfirmClicked();
}
});
}
}
#Override
public int getItemCount() {
return questionHolders.size() + 1;
}
#Override
public int getItemViewType(int position) {
return (position == questionHolders.size()) ? R.layout.question_recycler_confirm_button : R.layout.question_item;
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView txtQuestion;
public RadioGroup questionRadioGroup;
public RadioButton rBtnAnswer1;
public RadioButton rBtnAnswer2;
public RadioButton rBtnAnswer3;
public RadioButton rBtnAnswer4;
public Button btnConfirm;
public ViewHolder(#NonNull View itemView) {
super(itemView);
txtQuestion = itemView.findViewById(R.id.txtQuestion);
questionRadioGroup = itemView.findViewById(R.id.questionRadioGroup);
rBtnAnswer1 = itemView.findViewById(R.id.rBtnAnswer1);
rBtnAnswer2 = itemView.findViewById(R.id.rBtnAnswer2);
rBtnAnswer3 = itemView.findViewById(R.id.rBtnAnswer3);
rBtnAnswer4 = itemView.findViewById(R.id.rBtnAnswer4);
btnConfirm = itemView.findViewById(R.id.btnConfirm);
}
}
}
public class QuizActivity extends AppCompatActivity {
RecyclerView questionRecyclerView ;
QuestionRecyclerAdapter adapter ;
QuestionDatabaseHelper questionDatabaseHelper ;
Map<Integer,Boolean> answeredRecords = new HashMap<>();
int score ;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz);
questionRecyclerView = findViewById(R.id.questionRecyclerView);
questionDatabaseHelper = new QuestionDatabaseHelper(this);
int selectedId = getIntent().getIntExtra(Constants.SELECTED_ID,0);
score = 0 ;
List<QuestionHolder> questionHolders = questionDatabaseHelper.getAllQuestionHoldersById(selectedId);
adapter = new QuestionRecyclerAdapter(this,questionHolders);
questionRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
questionRecyclerView.setAdapter(adapter);
adapter.setOnQuestionAnswerSelect(new OnQuestionAnswerSelect() {
#Override
public void onAnswerSelected(int questionNumber, boolean isCorrect) {
answeredRecords.put(questionNumber,isCorrect);
}
});
adapter.setOnConfirmButtonClicked(new OnConfirmButtonClicked() {
#Override
public void onConfirmClicked() {
score = 0 ;
for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
if (item.getValue())
score++;
}
Log.e("THE SCORE IS ", String.valueOf(score));
}
});
}
private void displayRecords(){
for(Map.Entry<Integer,Boolean> item : answeredRecords.entrySet()){
Log.e("AAA",item.getKey() + " : " + item.getValue());
}
}
}
Make a function in adapter and send holder to activity by calling that function.
first make viewholder named holder1.
ViewHolder holder1;
then at the onBindViewHolder method add this:
holder1 = holder;
public ViewHolder getHolder(){
return holder1;
}
now you can use it in your Activity like this:
adapter.getHolder.rBtnAnswer1.setBackgroundColor(Color.parseColor("#FFFFFF")); //this is a example.
I've noticed RecyclerView "recycle" the views in the adapter but i want stop RecyclerView adapter duplicate the checked action in another item of the RecyclerView.
I have 10 items drawed into a RecyclerView, each one of them have a RadioGroup with 2 RadioButton within, but when i fired the check in the first item, for example, the number ten item have a checked too.
I was reading this question but i could'nt got it work.
Using Radio button with recyclerview in android
How to avoid this?
My adapter:
...
public class PreguntaAdapter extends RecyclerView.Adapter<PreguntaAdapter.ViewHolder> {
private Context context;
private ArrayList<VistaEncuestaActivity.PreguntasSiNo> preguntas;
public ArrayList<Respuestas> respuestas = new ArrayList<Respuestas>();
public PreguntaAdapter(Context context, ArrayList<VistaEncuestaActivity.PreguntasSiNo> preguntas) {
this.context = context;
this.preguntas = preguntas;
}
public ArrayList<Respuestas> getCheckedItems() {
return respuestas;
}
#NonNull
#Override
public PreguntaAdapter.ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
Context context = viewGroup.getContext();
LayoutInflater layoutInflater = LayoutInflater.from(context);
View v = layoutInflater.inflate(R.layout.item_pregunta_sino, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(#NonNull final PreguntaAdapter.ViewHolder viewHolder, int i) {
final VistaEncuestaActivity.PreguntasSiNo currentPregunta = preguntas.get(i);
//viewHolder.pregunta.setText(currentEncuesta.getString_pregunta());
viewHolder.pregunta.setText(currentPregunta.getQuestion());
viewHolder.myLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.setIsRecyclable(false);
}
#Override
public int getItemCount() {
return preguntas.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public SharedPreferences prefs;
private LinearLayout myLinearLayout;
public TextView pregunta;
public RadioGroup radio_group;
public ViewHolder(#NonNull View itemView) {
super(itemView);
pregunta = (TextView) itemView.findViewById(R.id.pregunta);
radio_group = (RadioGroup) itemView.findViewById(R.id.radio_group_pregunta);
prefs = (SharedPreferences) context.getSharedPreferences("logged", Context.MODE_PRIVATE);
myLinearLayout = (LinearLayout) itemView.findViewById(R.id.myLinearLayout);
}
}
}
Thanks all of you for your responses. Unfortunally any response helped me to solve this issue, i used this function and i added the getItemViewType function to my adapter and it's working well now:
#Override
public int getItemViewType(int position) {
return position;
}
And going to the official google docs i could find the next information:
Return the view type of the item at position for the purposes of view recycling. The default implementation of this method returns 0, making the assumption of a single view type for the adapter. Unlike ListView adapters, types need not be contiguous. Consider using id resources to uniquely identify item view types. https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter
This make sense at the time RecyclerView "recycle" the views but when this is use it in the adapter this have a different behavior treating each view as unique.
Thank you to all of you.
RadioGroup.getCheckedRadioButtonId() is the way to go. In conjunction with a SparseArray<Integer>.
In onBindViewHolder():
On each RadioGroup, set a RadioGroup.OnCheckedChangeListener(). Add the checked state to the a SparseArray or Map<Integer,Integer> mapping the index of the item position to the updated value in RadioGroup.OnCheckedChangeListener() onCheckedChanged.
So your onBindViewHolder would look something like this:
private SparseArray<Integer> mMapping = new SparseArray<>();
public void onBindViewHolder(#NonNull final PreguntaAdapter.ViewHolder viewHolder,final int position) {
final VistaEncuestaActivity.PreguntasSiNo currentPregunta = preguntas.get(i);
//viewHolder.pregunta.setText(currentEncuesta.getString_pregunta());
viewHolder.pregunta.setText(currentPregunta.getQuestion());
viewHolder.myLinearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
viewHolder.radio_group.setOnCheckedChangeListener(new OnCheckedChangeListener(){
void onCheckedChanged(RadioGroup group,int checked) {
mMapping.put(position,checked);
}
}};
// Check to see if a previous checked value exists and restore.
if(mMapping.get(position) != null && mMapping.get(position) != -1){
radio_group.check(mMapping.get(position));
}
viewHolder.setIsRecyclable(false);
}
onCheckedChanged(RadioGroup group, int checkedId)
You should give each RadioButton a unique ID, like radioButton_1, radioButton_2 in your layout file.