Android: Radio button in custom list view

a 夏天 提交于 2019-11-27 07:00:34

Here are the key ideas

  • when a RadioButton is checked we must call notifyDataSetChanged(), so that all views get updated.
  • when a RadioButton is checked we must set a selectedPosition, to keep track of which RadioButton is selected
  • Views are recycled inside ListViews. Therefore, their absolute position changes in the ListView. Therefore, inside ListAdapter#getView(), we must call setTag() on each RadioButton. This allows us to determine the current position of the RadioButton in the list when the RadioButton is clicked.
  • RadioButton#setChecked() must be updated inside getView() for new or pre-existing Views.

Here is an example ArrayAdapter I wrote and tested in order to demonstrate these ideas

public class MainActivity extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // I do no use these values anywhere inside the ArrayAdapter. I could, but don't.
        final Integer[] values = new Integer[] {1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,1,2,3,4,5,};

        ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, R.layout.row, R.id.textview, values) {

            int selectedPosition = 0;

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                View v = convertView;
                if (v == null) {
                    LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                    v = vi.inflate(R.layout.row, null);
                    RadioButton r = (RadioButton)v.findViewById(R.id.radiobutton);
                }
                TextView tv = (TextView)v.findViewById(R.id.textview);
                tv.setText("Text view #" + position);
                RadioButton r = (RadioButton)v.findViewById(R.id.radiobutton);
                r.setChecked(position == selectedPosition);
                r.setTag(position);
                r.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        selectedPosition = (Integer)view.getTag();
                        notifyDataSetChanged();
                    }
                });
                return v;
            }

        };
        setListAdapter(adapter);
    }
}

Try below adapter :

public class ChooseAdapter extends ArrayAdapter<LinkedHashMap<String, String>> {
private ArrayList<LinkedHashMap<String, String>> listMenu;

int position_id;

private LayoutInflater inflater;
Context context;

public ChooseAdapter(Activity activity,
        ArrayList<LinkedHashMap<String, String>> listMenu, int type) {

    super(activity, R.layout.choose_single_item, listMenu);
    this.listMenu = listMenu;

    context = activity.getApplicationContext();
    inflater = LayoutInflater.from(context);

}

public int getCount() {
    return listMenu.size();
}

public long getItemId(int position) {
    return position;

}

public static class ViewHolder

{
    public CheckBox chk;

}

public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder view;

    if (convertView == null) {

        view = new ViewHolder();

        convertView = inflater.inflate(R.layout.choose_single_item, null);
        view.chk = (CheckBox) convertView
                .findViewById(R.id.selection_checkbox);

        view.chk.setOnCheckedChangeListener(new OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView,
                    boolean isChecked) {
                // TODO Auto-generated method stub
                if (isChecked) {

                    listMenu.get((Integer) buttonView.getTag()).put(
                            "checked", "true");
                    for (int i = 0; i < listMenu.size(); i++) {
                        if (i != (Integer) buttonView.getTag()) {
                            if (listMenu.get(i).containsKey("checked"))
                                listMenu.get(i).remove("checked");
                        }
                    }
                } else {
                    listMenu.get((Integer) buttonView.getTag()).remove(
                            "checked");
                }

                notifyDataSetChanged();
            }
        });

        convertView.setTag(R.id.selection_checkbox, view.chk);
        convertView.setTag(view);

    }

    else {
        view = (ViewHolder) convertView.getTag();
    }
    view.chk.setTag(position);

    view.chk.setText(listMenu.get(position).get("name"));

    if (listMenu.get(position).containsKey("checked")) {
        view.chk.setChecked(true);
    } else
        view.chk.setChecked(false);

    return convertView;

}
}

And the layout that I am inflating is :

<?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="horizontal" >

<CheckBox
    android:id="@+id/selection_checkbox"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    android:text="abc"
    android:textColor="#8C8C8C"
    android:textSize="16sp" />

</LinearLayout>

Here, I have used the checkbox, you can also use radiobutton instead of it, nothing else is needed to change.

Hope it helps!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!