как предотвратить дублирование элементов при прокрутке или клавиатуре в динамических формах?

Привет всем, я создал проект для обследования в области. я загрузил вопрос в представление ресайклера, где текст редактирования, радиокнопка, флажок, счетчик генерируются динамически (для каждого нет отдельных файлов макета), я использовал новый текст редактирования и использовал текстовое средство, чтобы ответы динамически обновлялись в списке, чтобы он мог вернуться к основной активности, то есть из класса адаптера в класс активности. моя проблема в том, что текст редактирования, радиокнопки и т. д. дублируются, но не вопрос в текстовом представлении при прокрутке вверх или вниз или клавиатуре вниз после выполнения оператора if, например, ввода ввода внутри текста редактирования или изменения значения в счетчике, затем прокрутите вверх

примечание: - текстовое представление является статическим компонентом, динамический ввод добавляется в linearlayout внутри файла макета строки, который представляет собой textview и edittext, оба являются дочерними компонентами linearlayout на основе случая, когда тип ввода добавляется как 2-й дочерний элемент линейного макета

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>

вот пример видео

https://imgur.com/a/hi3Vb5a


person Lingam mohan krishnasen    schedule 25.12.2020    source источник
comment
попробуйте setHasStableIds(true); к адаптеру   -  person Zain    schedule 25.12.2020
comment
все та же проблема   -  person Lingam mohan krishnasen    schedule 25.12.2020


Ответы (1)


Я нашел решение, кажется, проблема совсем в другом. Проблема в том, что представление ресайклера не перерабатывается должным образом, у него есть viewCachesize, который необходимо увеличить до размера списка.

вы можете проверить, перерабатывается ли ваш recyclerview или не используется

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

если журнал появляется, вы решаете эту проблему, добавляя

holder.setIsRecyclable(false);

в onbindviewholder или добавив

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

в самом основном действии. Очевидно, просто используйте сам список вместо recyclerview, тогда эти строки не нужно добавлять

ссылки: - RecyclerView не перезапускает просмотры, если количество просмотров маленький

Как я могу обнаружить перезапуск из адаптера recyclerView, чтобы я мог выполнить действие до того, как он будет перезапущен?

person Lingam mohan krishnasen    schedule 25.12.2020
comment
кажется, есть новая проблема: список ответов формы очищается при прокрутке вниз, а также при прокрутке снизу вверх, то же самое не в случае с отключенным кешем или setIsrecycleable (false) - person Lingam mohan krishnasen; 25.12.2020