【问题标题】:View holder Radio button with list view具有列表视图的视图持有者单选按钮
【发布时间】:2018-08-13 05:24:25
【问题描述】:

我正在尝试使用列表视图自定义适配器开发一个测验应用程序,但是当我选择一个单选按钮并向下滚动时,我看到另一个单选按钮被自动选中,我使用了视图持有者,但我不知道如何解决这个问题问题。

Here is my Video.

我的自定义适配器的代码。

问题适配器

public class QuestionAdapter2 extends ArrayAdapter<Question> {

    Context context;
    ArrayList<Question> questionArrayList;

    public QuestionAdapter2(Context context, ArrayList<Question> questionArrayList) {
        super(context, R.layout.question_listitem, questionArrayList);
        this.context = context;
        this.questionArrayList = questionArrayList;

    }

    static class ViewHolder {
        protected TextView question;
        protected RadioButton choice1;
        protected RadioButton choice2;
        protected RadioButton choice3;
        protected RadioButton choice4;
    }

    @NonNull
    @Override
    public View getView(final int position, @Nullable View convertView, @NonNull ViewGroup parent) {

        ViewHolder viewHolder = null;

        if(convertView == null)
        {
            LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView=inflater.inflate(R.layout.question_listitem,parent,false);

            viewHolder = new ViewHolder();

            viewHolder.question = convertView.findViewById(R.id.question);
            viewHolder.choice1 = convertView.findViewById(R.id.choice1);
            viewHolder.choice2 = convertView.findViewById(R.id.choice2);
            viewHolder.choice3 = convertView.findViewById(R.id.choice3);
            viewHolder.choice4 = convertView.findViewById(R.id.choice4);

            viewHolder.choice1.setSelected(false);
            viewHolder.choice2.setSelected(false);
            viewHolder.choice3.setSelected(false);
            viewHolder.choice4.setSelected(false);


            convertView.setTag(viewHolder);
        }

        else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }


        viewHolder.choice1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                questionArrayList.get(position).setChoice1Selected(true);
                questionArrayList.get(position).setChoice2Selected(false);
                questionArrayList.get(position).setChoice3Selected(false);
                questionArrayList.get(position).setChoice4Selected(false);
                Toast.makeText(context, ""+Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.choice2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                questionArrayList.get(position).setChoice1Selected(false);
                questionArrayList.get(position).setChoice2Selected(true);
                questionArrayList.get(position).setChoice3Selected(false);
                questionArrayList.get(position).setChoice4Selected(false);
                Toast.makeText(context, ""+Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.choice3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                questionArrayList.get(position).setChoice1Selected(false);
                questionArrayList.get(position).setChoice2Selected(false);
                questionArrayList.get(position).setChoice3Selected(true);
                questionArrayList.get(position).setChoice4Selected(false);
                Toast.makeText(context, ""+Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.choice4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                questionArrayList.get(position).setChoice1Selected(false);
                questionArrayList.get(position).setChoice2Selected(false);
                questionArrayList.get(position).setChoice3Selected(false);
                questionArrayList.get(position).setChoice4Selected(true);
                Toast.makeText(context, ""+Integer.toString(position), Toast.LENGTH_SHORT).show();
            }
        });

        viewHolder.question.setText(questionArrayList.get(position).getQuestion().toString());
        viewHolder.choice1.setText(questionArrayList.get(position).getCoice1().toString());
        viewHolder.choice2.setText(questionArrayList.get(position).getCoice2().toString());
        viewHolder.choice3.setText(questionArrayList.get(position).getCoice3().toString());
        viewHolder.choice4.setText(questionArrayList.get(position).getCoice4().toString());


        viewHolder.choice1.setSelected(questionArrayList.get(position).getChoice1Selected());
        viewHolder.choice2.setSelected(questionArrayList.get(position).getChoice2Selected());
        viewHolder.choice3.setSelected(questionArrayList.get(position).getChoice3Selected());
        viewHolder.choice4.setSelected(questionArrayList.get(position).getChoice4Selected());

        return convertView;

    }
}

这是我的 xml 文件。

XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/question"
        android:text="Question"
        android:textSize="30sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <RadioGroup
        android:id="@+id/radioGroup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <RadioButton
            android:id="@+id/choice1"
            android:text="choice1"
            android:textSize="18sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/choice2"
            android:text="choice2"
            android:textSize="18sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/choice3"
            android:text="choice3"
            android:textSize="18sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />

        <RadioButton
            android:id="@+id/choice4"
            android:text="choice4"
            android:textSize="18sp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    </RadioGroup>



</LinearLayout>

【问题讨论】:

  • 你知道回收站视图。
  • 你为什么不使用广播组?
  • 我正在使用广播组,您可以从我提供的视频中查看。
  • 那么对于单选组,为什么要为所有 4 个单选按钮设置值?单选组默认只有一个选择
  • 如果您正在执行此代码。那么你对 RadioGroup 的功能了解不够。

标签: java android xml custom-adapter


【解决方案1】:

我有很多建议给你。我们从这里开始。

  • 使用 RecyclerView 代替 ListView。已经有很多开发人员遇到了您的问题,RecyclerView 应运而生。
  • 使用 RadioGroup 而不是管理 4 个复选框。如果您将来需要 10 个单选按钮,那么您将管理 10 个按钮怎么办?您只需按住单选按钮 ID。然后在提交表单时处理选定的 Id。

喜欢

rGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
{
    public void onCheckedChanged(RadioGroup group, int checkedId)
    {
        RadioButton checkedRadioButton = (RadioButton)group.findViewById(checkedId);
        boolean isChecked = checkedRadioButton.isChecked();
        if (isChecked)
        {
          your radio button is checked. you can put this radio button id in your question mode.
        }
    }
});
  • 从列表中获取项目一次,然后在任何地方使用。

喜欢

    Question q = questionArrayList.get(position); // use everywhere instead of fetching from List.
    viewHolder.choice1.setSelected(q.getChoice1Selected());
    viewHolder.choice2.setSelected(q.getChoice2Selected());
    viewHolder.choice3.setSelected(q.getChoice3Selected());
    viewHolder.choice4.setSelected(q.getChoice4Selected());

【讨论】:

    【解决方案2】:

    尝试此代码并根据您的代码进行更改,并将一个布尔字段带入问题 pojo 类..

    public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.ItemViewHolder> {
    List<Question> mQuestionList = new ArrayList<>();// hear you can pass any pojo class object.
    Context mContext;
    OnItemClick onItemClick;
    
    public void setOnItemClick(OnItemClick onItemClick) {
        this.onItemClick = onItemClick;
    }
    
    public interface OnItemClick {
        void getPosition(Question data); //pass any data to shared it.
    }
    
    public RecyclerViewAdpater(List<Question> mQuestionList, Context mContext) {
        this.mQuestionList = mQuestionList;
        this.mContext = mContext;
    }
    
    @Override
    public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.activity_main, parent, false);
        return new ItemViewHolder(view);
    }
    
    @Override
    public void onBindViewHolder(final ItemViewHolder holder, final int position) {
        // below code handle click event on recycler view item.
        final Question str=mQuestionList.get(position); //  here your boject
        holder.textView.setText(str.getName());
        if (str.isSelected()){
            // hear set your radio button select or unselect.
            holder.textView.setVisibility(View.GONE);
        }
        holder.textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                onItemClick.getPosition(str);
            }
        });
    
    }
    
    @Override
    public int getItemCount() {
        return mQuestionList.size();
    }
    
    public class ItemViewHolder extends RecyclerView.ViewHolder {
        TextView textView;
    
        public ItemViewHolder(View itemView) {
            super(itemView);
            textView=itemView.findViewById(R.id.textView);
        }
    }
    }
    

    适配器定义后意味着适配器绑定到回收器视图并且适配器不为空然后调用下面的代码..

            adpater.setOnItemClick(new RecyclerViewAdpater.OnItemClick() {
            @Override
            public void getPosition(Question data) {
                // perform any operation here.
                data.setSelected(true);
                adpater.notifyDataSetChanged();
            }
        });
    

    如果您为您引用相同的 cod,则只需为 mange 选择或取消选择单选按钮取一个布尔值。

    【讨论】:

      【解决方案3】:

      之所以选择另一个单选按钮,是因为ListView会复用itemView。在您的情况下,如果您在第一项中选择一个单选按钮,则滚动到最初不可见的第五项,第五项变为可见,同时第一项变为不可见,因此第五项将直接使用第一项。

      为解决您的问题,您可以修改else附近的代码。

      else
      {
          viewHolder = (ViewHolder) convertView.getTag();
          // add below code to solve uncorrect state
          viewHolder.choice1.setSelected(false);
          viewHolder.choice2.setSelected(false);
          viewHolder.choice3.setSelected(false);
          viewHolder.choice4.setSelected(false);
      }
      

      真诚地建议您尽快使用 RecyclerView。

      【讨论】:

        【解决方案4】:

        我会推荐使用 RecyclerView。它是随 Android Lollipop 一起推出的,事实证明它改变了游戏规则。我们在 ListView 中讨厌的很多东西在 RecyclerView 中得到了修复或更改。默认情况下效率更高。

        如果你仍然想使用相同的列表视图,你应该从活动中传递值以避免这种扫描。希望它被理解。

        【讨论】:

          【解决方案5】:

          尝试在您的适配器中使用 if else,如下所示为每个单选按钮

           if(questionArrayList.get(position).getChoice1Selected())
           {  
          viewHolder.choice1.setSelected(true);
            }else{  
          viewHolder.choice1.setSelected(false);
           }      
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-03
            • 1970-01-01
            • 1970-01-01
            • 2018-09-19
            • 2013-03-10
            • 1970-01-01
            相关资源
            最近更新 更多