Android: Radio button in custom list view

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);
    }
}

Leave a Comment