【问题标题】:how to prevent items getting duplicated onscroll or keyboard in dynamic forms?如何防止项目在动态表单中重复滚动或键盘?
【发布时间】:2020-12-25 04:17:30
【问题描述】:

大家好,我已经为该地区的调查创建了项目。我已经在回收器视图中加载了问题,其中动态生成了edittext、radiobutton、checkbox、spinner(每个都没有单独的布局文件)我使用了新的edittext并使用了textwatcher来保持答案在列表中动态更新,以便它可以返回主活动,即从适配器类到活动类。我的问题是edittext、radiobuttons等被重复但不是textview中的问题在向上或向下滚动或键盘向下之后如果操作员执行像在edittext中输入输入或在微调器中更改值然后向上滚动

注意:- textview 是静态组件,动态输入被添加到行布局文件内的线性布局中,即 textview 和 edittext 都是线性布局的子组件,如果输入类型被添加为线性布局的第二个子级

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

【问题讨论】:

  • 尝试setHasStableIds(true);到适配器
  • 还是同样的问题

标签: android android-recyclerview android-linearlayout dynamic-forms


【解决方案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);

在主要活动本身 显然只使用 listview 本身而不是 recyclerview 然后这些行不需要添加

链接:- 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?

【讨论】:

  • 似乎有一个新问题,formanswerlist 在向下滚动并从下到上向上滚动时被清除,缓存关闭或 setIsrecycleable(false) 的情况并非如此
猜你喜欢
  • 2011-09-19
  • 2014-05-30
  • 1970-01-01
  • 2016-01-23
  • 2018-06-10
  • 2017-12-15
  • 2014-09-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多