22

I want to make a custom List View having Two TextViews and a radio Button in a single row. And on listitem click the radio button state should be toggle. I cannot use Simple Adapter here.

I have already asked that question Single choice ListView custom Row Layout but don't find any satisfactory solution.

What I am currently doing is I am using simple_list_item_single_choice and putting data of both TextViews in a single one separated by some white spaces. But here it is getting worse (shown in the image below).

http://db.tt/ulP6pn7V

What I want is to fix the location of size and price and make list view as single choice.

XML Layout for the list can be something like:

**<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_size"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="15sp"
        android:width="200dp" />

    <TextView
        android:id="@+id/tv_price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="15sp"
        android:width="70dp" />

    <RadioButton
        android:id="@+id/radioButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>**

How to make custom adapter for that?

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63
Nitin4Android
  • 864
  • 2
  • 12
  • 25

6 Answers6

96

I had a similar situation but fixed that easily. Try this:

  1. Extend ListActivity and set your custom list adapter

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE); //if you need title to be hidden
        setContentView(R.layout.activity_add_to_cart_select_service_plan);
        setListAdapter(adapter);
    }
    
  2. Create a field to store selected index position in adapter

    int selectedIndex = -1;
    
  3. Provide an interface to it

    public void setSelectedIndex(int index){
        selectedIndex = index;
    }
    
  4. Set the checked state to true or false based on the selected index inside getView()

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RadioButton rbSelect = (RadioButton) convertView
                            .findViewById(R.id.radio1);
        if(selectedIndex == position){
        rbSelect.setChecked(true);
        }
        else{
        rbSelect.setChecked(false);
        }
    }
    
  5. Set radio button focusable and clickable attribs to 'false'

     <RadioButton
         android:id="@+id/radio1"
         android:checked="false"
         android:focusable="false"
         android:clickable="false"
     />
    
  6. Set listview descendantFocusability attrib to 'beforeDescendants'

    <ListView
        android:id="@android:id/list"
        android:choiceMode="singleChoice"
        android:descendantFocusability="beforeDescendants"
    />
    
  7. Override onListItemClick

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);
        adapter.setSelectedIndex(position);
        adapter.notifyDataSetChanged();
    }
    

That's it..run and check

SteveR
  • 2,496
  • 1
  • 24
  • 23
skpal202
  • 1,217
  • 1
  • 9
  • 9
12

I've been searching for an answer to this problem all morning, and the most useful thing I've found so far is this article.

While I haven't implemented the solution it suggests yet, it sounds like it's on the right track.

Basically, the single-choice ListView expects the widgets you provide it with to implement the Checkable interface. LinearLayout and others don't. So you need to create a custom layout that inherits LinearLayout (or whatever layout you want to use for your items) and implements the necessary interface.

Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
Jules
  • 14,841
  • 9
  • 83
  • 130
  • 1
    Definitely the way to go. The link has all you need, just use that class and reference it in your XML as shown. – Fraggle Dec 29 '11 at 22:17
  • Thank you very much - definetely helpful! – Rikki Tikki Tavi Aug 22 '13 at 10:28
  • 4
    If you want to use your own layout, f.e. with RadioButtons instead of CheckableTextView remember to set android:focusable="false" android:focusableInTouchMode="false" for the button. – philips77 Aug 15 '14 at 14:43
5

Handled a similar issue with a Hack (Not a perfect solution..but still works..)

 listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {




                for (int i = 0; i < parent.getCount() ; i ++)
                {

                    View v = parent.getChildAt(i);
                    RadioButton radio = (RadioButton) v.findViewById(R.id.radio);
                    radio.setChecked(false);

                }

                    RadioButton radio = (RadioButton) view.findViewById(R.id.radio);
                    radio.setChecked(true);



            }
        });
ASP
  • 3,645
  • 1
  • 31
  • 45
0

Try setting the android:choiceMode attribute of the ListView

<ListView
    ...
    android:choiceMode="singleChoice" />
Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80
0

Modify the component as you like, without multiple layouts

row_custom.xml

<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:checkMark="@drawable/custom_drawable"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd" />

MainActivity.java

ArrayAdapter<String> adapter = new ArrayAdapter(context, R.layout.row_custom, mList);
Mohamed Rahal
  • 61
  • 1
  • 3
-1

**

<TextView
    android:id="@+id/tv_size"
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:text="TextView"
    android:textSize="15sp"
    android:width="200dp" />

<TextView
    android:id="@+id/tv_price"
    android:layout_width="70dp"
    android:layout_height="wrap_content"
    android:text="TextView"
    android:textSize="15sp"
    android:width="70dp" />

<RadioButton
    android:id="@+id/radioButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

**

Shailendra Singh Rajawat
  • 8,172
  • 3
  • 35
  • 40