Custom Single choice ListView
Asked Answered
F

6

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?

Furfural answered 1/12, 2011 at 6:0 Comment(3)
check out this tutorial vogella.de/articles/AndroidListView/article.htmlWafture
You can check this example in GitHubPrepared
Check this for future reference youtube.com/watch?v=s4JwU28VMkoTheona
P
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.

Physicist answered 14/12, 2011 at 9:26 Comment(2)
Definitely the way to go. The link has all you need, just use that class and reference it in your XML as shown.Microcurie
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.Fielding
B
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

Boxwood answered 10/10, 2012 at 15:52 Comment(1)
This should be the accepted answer. Quick and easy to implement.Raman
P
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.

Physicist answered 14/12, 2011 at 9:26 Comment(2)
Definitely the way to go. The link has all you need, just use that class and reference it in your XML as shown.Microcurie
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.Fielding
C
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);



            }
        });
Clamber answered 5/2, 2015 at 12:47 Comment(1)
This is the best solution. Not a hack. It's simple and flawless.Glabrous
H
0

Try setting the android:choiceMode attribute of the ListView

<ListView
    ...
    android:choiceMode="singleChoice" />
Heinrick answered 28/4, 2022 at 22:28 Comment(0)
S
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);
Seminal answered 22/4, 2023 at 9:1 Comment(0)
P
-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" />

**

Painful answered 1/12, 2011 at 6:11 Comment(5)
@ Chunhui :- I have throughly read that Article already but can't find desired answer.Furfural
@ Shailendra Rajawat :- Cannot get what you wanna say.Furfural
android:layout_width should not be wrap_content when you want specific width . if this replacement too can not work share the code and issuePainful
@ Shailendra Rajawat :- That is not an issue, what I want is List View to be single choice and work properly.Furfural
by default its single choice . perhaps you did not used efficient Adapter (one with handler class) , so seeing unexpected radio buttons on . search for efficientAdapter and use it .Painful

© 2022 - 2024 — McMap. All rights reserved.