how to prevent items getting duplicated onscroll or keyboard in dynamic forms?

Hi everyone i have created project for survey in area. i have loaded the question in the recycler view where edittext,radiobutton,checkbox,spinner are generated dynamically(there no separate layout files for each) i have used new edittext and used textwatcher to keep the answers dynamically updated in the list so that it can return to mainactivity i.e from adapterclass to activity class. my problem is that the edittext, radiobuttons,etc are getting duplicated but not the question in the textview on scroll up or down or keyboard down after the if there operator performed like enter input inside edittext or change value in spinner then scroll up

note:- the textview is static component the dynamic input are add to linearlayout inside the row layout file that is textview and edittext are both childcomponents of linearlayout based on if case the input type is added as 2nd child of linear layout

Activity.class

 mlist=new ArrayList<>();
    mlist.clear();
    mlist=db.populatequestion();
    Log.d("size", String.valueOf(mlist.size()));
    Log.d("Question",mlist.get(0).getQuestionType());
    mRecyclerView=findViewById(R.id.rvForm);
    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);
    formsadapter =new formsadapter(mlist,this,mRecyclerView);
    mRecyclerView.setAdapter(formsadapter);

formsadapter.class

public class formsadapter extends RecyclerView.Adapter<formsadapter.ViewHolder> {
private List<FormQData> mlists;
private List<formanswer> formanswers;
private Context mContext1;
private RecyclerView mRecyclerV1;
public class ViewHolder extends RecyclerView.ViewHolder{
    public LinearLayout linearLayout;
    public TextView Question;
    public View layout;
    public ViewHolder(View v) {
        super(v);
        layout=v;
        Question=v.findViewById(R.id.tvQuestion);
        linearLayout=v.findViewById(R.id.llform);
        formanswers = new ArrayList<>();
    }
}

public formsadapter(List<FormQData> myDataset, Context context, RecyclerView recyclerView) {
    mlists = myDataset;
    mContext1 = context;
    mRecyclerV1 = recyclerView;
}
public formsadapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                  int viewType){
    LayoutInflater inflater = LayoutInflater.from(
            parent.getContext());
    View v =inflater.inflate(R.layout.row_form, parent, false);
    ViewHolder vh = new ViewHolder(v);
    return vh;
}
public void onBindViewHolder(formsadapter.ViewHolder holder, final int position){
    final FormQData fb=mlists.get(position);
    formanswer fa=new formanswer();
    holder.Question.setText(fb.getQuestionContent());
    LinearLayout.LayoutParams mainparams1 = new LinearLayout.LayoutParams(
            LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT,1.0f);
    mainparams1.gravity= Gravity.RIGHT;
    if(fb.getQuestionType().equals("textbox")){
        EditText et=new EditText(mContext1);
        et.setBackgroundResource(R.drawable.boxwithcircularcoloredborders);
        et.setTextColor(mContext1.getResources().getColor(R.color.colorPrimary));
        et.setPadding(15,15,15,15);
        et.addTextChangedListener(new TextWatcher() {
            @Override public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
            @Override public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {}
            @Override
            public void afterTextChanged(Editable editable) {
                fa.setQuestionid(fb.getQuestionid());
                fa.setAnswer(et.getText().toString());
                if(formanswers.contains(fa)){
                    formanswers.set(formanswers.indexOf(fa),fa);
                }
                else
                    formanswers.add(fa);
            }
        });
        holder.linearLayout.addView(et,1);
    }
    else if(fb.getQuestionType().equals("radiobox")){
        RadioGroup rg=new RadioGroup(mContext1);
        rg.setOrientation(RadioGroup.HORIZONTAL);
        String[] arrOfStr = fb.getQuestionOptions().split(":");
        RadioButton[] radiobutton = new RadioButton[arrOfStr.length];
        for(int i=0;i<arrOfStr.length;i++){
            radiobutton[i]=new RadioButton(mContext1);
            radiobutton[i].setText(arrOfStr[i]);
            radiobutton[i].setLayoutParams(mainparams1);
            radiobutton[i].setBackgroundResource(R.drawable.boxwithcircularcoloredborders);
            radiobutton[i].setTextColor(mContext1.getResources().getColor(R.color.colorPrimary));
            radiobutton[i].setTypeface(Typeface.DEFAULT_BOLD);
            radiobutton[i].setPadding(15,15,15,15);
            int finalI = i;
            radiobutton[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    fa.setQuestionid(fb.getQuestionid());
                    fa.setAnswer(radiobutton[finalI].getText().toString());
                    if(formanswers.contains(fa)){
                        formanswers.set(formanswers.indexOf(fa),fa);
                    }
                    else
                        formanswers.add(fa);
                }
            });
            rg.addView(radiobutton[i],i);
        }
        holder.linearLayout.addView(rg,1);
    }
    else if(fb.getQuestionType().equals("checkbox")){
        List<String> answer=new ArrayList<>();
        RadioGroup rg=new RadioGroup(mContext1);
        rg.setOrientation(RadioGroup.HORIZONTAL);
        String[] arrOfStr = fb.getQuestionOptions().split(":");
        CheckBox[] checkBoxes = new CheckBox[arrOfStr.length];
        for(int i=0;i<arrOfStr.length;i++){
            checkBoxes[i]=new CheckBox(mContext1);
            checkBoxes[i].setText(arrOfStr[i]);
            checkBoxes[i].setLayoutParams(mainparams1);
            checkBoxes[i].setBackgroundResource(R.drawable.boxwithcircularcoloredborders);
            checkBoxes[i].setTextColor(mContext1.getResources().getColor(R.color.colorPrimary));
            checkBoxes[i].setTypeface(Typeface.DEFAULT_BOLD);
            checkBoxes[i].setPadding(15,15,15,15);
            int finalI = i;
            checkBoxes[i].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    fa.setQuestionid(fb.getQuestionid());
                    if(checkBoxes[finalI].isChecked()){
                        String temp=checkBoxes[finalI].getText().toString();
                        if(answer.contains(temp)){
                            answer.set(answer.indexOf(temp),temp);
                        }else {
                            answer.add(checkBoxes[finalI].getText().toString());
                        }
                    }else{
                        answer.remove(checkBoxes[finalI].getText().toString());
                    }
                    fa.setAnswer(answer.toString());
                    if(formanswers.contains(fa)){
                        formanswers.set(formanswers.indexOf(fa),fa);
                    }
                    else
                        formanswers.add(fa);
                }
            });
            rg.addView(checkBoxes[i],i);
        }
        holder.linearLayout.addView(rg,1);
    }
    else if(fb.getQuestionType().equals("dropdown")){
        Spinner spinner=new Spinner(mContext1);
        fa.setQuestionid(fb.getQuestionid());
        List<String> arrOfStr=new ArrayList<>(Arrays.asList(fb.getQuestionOptions().split(":")));
        arrOfStr.add(0,"Select A Option");
        ArrayAdapter<String> spinnerAdapter=new ArrayAdapter<>(mContext1,R.layout.row_dropdownsinglecelltv,R.id.tvsinglecell2,arrOfStr);
        spinnerAdapter.setDropDownViewResource(R.layout.row_dropdownsinglecelltv);
        spinner.setPopupBackgroundDrawable(mContext1.getResources().getDrawable(R.drawable.boxcircularcorner));
        spinner.setAdapter(spinnerAdapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                String spinnerValue=String.valueOf(adapterView.getSelectedItem());
                if (!spinnerValue.equals("Select A Option")){
                    //Log.d("value","upload");
                    fa.setAnswer(spinnerValue);
                    if(formanswers.contains(fa))
                        formanswers.set(formanswers.indexOf(fa),fa);
                    else
                        formanswers.add(fa);
                }else{
                    if(formanswers.contains(fa))
                        formanswers.remove(fa);
                }

            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        });
        holder.linearLayout.addView(spinner,1);
    }
    else {
        TextView et=new TextView(mContext1);
        et.setText("invalid question type");
        holder.linearLayout.addView(et,1);
    }
}
public int getItemCount(){
    return  mlists.size();
}
@Override
public long getItemId(int position) {
    return position;
}
@Override
public int getItemViewType(int position) {
    return position;
}
public List<formanswer> formanswers(){
    return formanswers;
}

}

row_form.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:padding="10dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">
<LinearLayout
    android:id="@+id/llform"
    android:background="@drawable/boxwithcoloredborder"
    android:layout_width="match_parent"
    android:padding="15dp"
    android:layout_height="wrap_content"
    android:orientation="vertical">



    <TextView
        android:id="@+id/tvQuestion"
        android:padding="5dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/colorPrimary"
        android:textStyle="bold"
        android:text="TextView" />

</LinearLayout>
</LinearLayout>

here is the sample video

https://i.sstatic.net/08WnE.jpg

Upvotes: 0

Views: 358

Answers (1)

i have found the solution it seems the problem is entirely different. The problem is that the recycler view is not getting recycled properly its has viewCachesize which needs to be increased to list size

you can check if your recyclerview is getting recycled or not using

@Override
    public void onViewRecycled(@NonNull formsadapter.ViewHolder holder) {
   Log.d("recyclerview","recyclerview is recycled");
    }

if the log is being appeared then you solve this issue adding

holder.setIsRecyclable(false);

in the onbindviewholder or adding

mRecyclerView.setItemViewCacheSize(mlist.size()+1);

in the main activity itself Evidently just use the listview itself instead of recyclerview then these lines dont need to be added

links:- RecyclerView not recycling views if the view count is small

How can I detect recycling from within a recyclerView adapter, so I can perform an action before it gets recycled?

Upvotes: 1

Related Questions