带列表视图的View Holder单选按钮

时间:2018-08-13 05:24:26

标签: java android xml custom-adapter

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

Here is my Video.

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

QuestionAdapter

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>

5 个答案:

答案 0 :(得分:0)

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

  • 使用 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());

答案 1 :(得分:0)

尝试此代码并根据您的代码进行更改,然后将一个布尔值字段放入问题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);
    }
}
}

在适配器定义之后,这意味着适配器绑定到回收器视图,并且适配器不为null,然后调用以下代码。

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

如果您将相同的鳕鱼作为参考,则仅对mange select或un select单选按钮使用一个布尔值。

答案 2 :(得分:0)

之所以选择另一个单选按钮,是因为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。

答案 3 :(得分:0)

我建议使用RecyclerView。它是随Android Lollipop一起引入的,事实证明它可以改变游戏规则。我们在ListView中讨厌的很多东西在RecyclerView中已修复或更改。默认情况下效率更高。

如果您仍要使用相同的列表视图,则应从activity传递值,以避免这种scanerio.hope理解它。

答案 4 :(得分:0)

尝试为每个单选按钮在适配器中使用if else

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