Android ListView with RadioButton in singleChoice mode and a custom row layout

前端 未结 7 1830
野趣味
野趣味 2020-12-06 04:13

I have a ListView, which is in singleChoice mode. All I want is to display a RadioButton to the side, that when clicked highlights to say i

相关标签:
7条回答
  • 2020-12-06 04:52

    Do bear in mind that in the ListView row items are RECYCLED. This is likely to explain why actions on one row are affecting another. Dig around in Mark's book and you'll find coverage of this.

    If you're using an adapter with the list, you can use getView() on an adapter to add a click handler to each row as it's created/recycled, and make sure the state is managed correctly as the row items are created and recycled.

    My approach is to store the state in my own data structure, and then use getView() to mirror that in the UI as the user scrolls up and down the ListView. There may be a better solution, but that works for me.

    0 讨论(0)
  • 2020-12-06 04:58

    Simple solution:

    Add this line in the RadioButton layout of your xml file:

    <RadioButton 
       ...
       android:onClick="onClickRadioButton"
       ...
    />
    

    Then in the activity class that uses the ListView, add the following:

       private RadioButton listRadioButton = null;
       int listIndex = -1;
    
       public void onClickRadioButton(View v) {
            View vMain = ((View) v.getParent());
            // getParent() must be added 'n' times, 
            // where 'n' is the number of RadioButtons' nested parents
            // in your case is one.
    
            // uncheck previous checked button. 
            if (listRadioButton != null) listRadioButton.setChecked(false);
            // assign to the variable the new one
            listRadioButton = (RadioButton) v;
            // find if the new one is checked or not, and set "listIndex"
            if (listRadioButton.isChecked()) {
                listIndex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain); 
            } else {
                listRadioButton = null;
                listIndex = -1;
            }
        }
    

    With this simple code only one RadioButton is checked. If you touch the one that is already checked, then it returns to the unchecked mode.

    "listIndex" is tracking the checked item, -1 if none.

    If you want to keep always one checked, then code in onClickRadioButton should be:

       public void onClickRadioButton(View v) {
            View vMain = ((View) v.getParent());
            int newIndex = ((ViewGroup) vMain.getParent()).indexOfChild(vMain);
            if (listIndex == newIndex) return;
    
            if (listRadioButton != null) {
                    listRadioButton.setChecked(false);
            }
            listRadioButton = (RadioButton) v;
            listIndex = newIndex; 
        }
    
    0 讨论(0)
  • 2020-12-06 05:04

    My Name Is Gourab Singha. I solved This Issue. I have Written This Code to solve it. I hope this helps you all. Thanks. I require 3 hours for this.

    public void add_option_to_list(View v){
    
    
        LinearLayout ll = (LinearLayout)v.getParent();
        LinearLayout ll_helper = null; 
        LinearLayout ll2 =  (LinearLayout)ll.getParent();
        LinearLayout ll3 =  (LinearLayout)ll2.getParent();
    
        ListView ll4 =  (ListView)ll3.getParent();
        //RadioButton rb1= (RadioButton)ll.getChildAt(1);
        Toast.makeText(getApplicationContext(), ", "+ll4.getChildCount(), Toast.LENGTH_LONG).show();    
        //ll.findViewById(R.id.radio_option_button)
        for(int k=0;k<ll4.getChildCount();k++){
    
            ll3 = (LinearLayout)ll4.getChildAt(k);
            ll2 = (LinearLayout)ll3.getChildAt(0);
            ll_helper = (LinearLayout)ll2.getChildAt(0);
            RadioButton rb1 = (RadioButton)ll_helper.getChildAt(1);
            if(rb1.isChecked())
            rb1.setChecked(false);
    
    
        }
        RadioButton rb1 = (RadioButton)ll.getChildAt(1);
        rb1.setChecked(true);
        //Toast.makeText(getApplicationContext(), ""+((TextView)ll.getChildAt(4)).getText().toString(), Toast.LENGTH_LONG).show();
    
    
        }
    

    The 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="match_parent"
        android:orientation="vertical" >
    
        <LinearLayout
    
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
    
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal" >
    
                <TextView
                    android:id="@+id/id"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Category Name"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:visibility="gone" />
    
                <RadioButton
                    android:id="@+id/radio_option_button"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:onClick="add_option_to_list"
                    android:text="" />
    
                <TextView
                    android:id="@+id/option_name"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:layout_marginLeft="3dp"
                    android:layout_weight="5.35"
                    android:text="Category Name"
                    android:textAppearance="?android:attr/textAppearanceMedium" />
    
    
    
                <TextView
                    android:id="@+id/option_price"
                    android:layout_width="76dp"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10dp"
                    android:gravity="right"
                    android:text="$0.00"
                    android:textAppearance="?android:attr/textAppearanceMedium" />
    
                <TextView
                    android:id="@+id/option_unit_price"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="5dp"
                    android:gravity="right"
                    android:text="$0.00"
                    android:textAppearance="?android:attr/textAppearanceMedium"
                    android:visibility="gone" />
            </LinearLayout>
    
        </LinearLayout>
    
    </LinearLayout>
    
    0 讨论(0)
  • 2020-12-06 05:07

    On your adapter:

    public void setChecked(View v, int position) {
    
        ViewGroup parent = ((ViewGroup) v.getParent()); // linear layout
    
        for (int x = 0; x < parent.getChildCount() ; x++) {
    
            View cv = parent.getChildAt(x);
            ((RadioButton)cv.findViewById(R.id.checkbox)).setChecked(false); // your checkbox/radiobtt id
        }
    
        RadioButton radio = (RadioButton)v.findViewById(R.id.checkbox);
        radio.setChecked(true);
    }
    

    On your activity/fragment:

       listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                ((ModelNameAdapter)adapter).setChecked(view, position);
    
            }
        });
    
    0 讨论(0)
  • 2020-12-06 05:08

    You can achieve much more simple, follow this. It was tried in MarshMallow

    1)Have a CheckedTextView :

    <CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:checkMark="?android:attr/listChoiceIndicatorSingle"
        android:padding="10dp"
        android:textAppearance="?android:attr/textAppearanceMedium">
    

    • ListChoiceIndicatorSingle will display RadioButton.

    • ListChoiceIndicatorMultiple will display CheckBox

    Don't forgot to put choiceMode:Single in your ListView.

    0 讨论(0)
  • 2020-12-06 05:11

    Inside the adapter

     viewHolder.radioBtn.setOnClickListener(new OnClickListener() {
    
                   @Override
                   public void onClick(View v) {
                       Log.e("called", "called");
                       if(position != mSelectedPosition && mSelectedRB != null){
                           mSelectedRB.setChecked(false);
                       }
    
    
    
                       mSelectedPosition = position;
                       mSelectedRB = (RadioButton)v;
                   }
               });
    
               viewHolder.radioBtn.setText(mList[position]);  
               if(mSelectedPosition != position){
                   viewHolder.radioBtn.setChecked(false);
    
               }else{
                   viewHolder.radioBtn.setChecked(true);
    
                   if(mSelectedRB != null && viewHolder.radioBtn != mSelectedRB){
                       mSelectedRB = viewHolder.radioBtn;
                   }
               }
    

    add style to the radio button

    <?xml version="1.0" encoding="utf-8"?>
     <selector xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item android:drawable="@drawable/tick" android:state_checked="true"/>
        <item android:drawable="@drawable/untick" android:state_checked="false"/>
    
     </selector>
    

    and in the xml use the radio button style

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <RadioButton
            android:id="@+id/radioBtn"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:button="@null"
            android:checked="true"
            android:drawablePadding="30dp"
            android:drawableRight="@drawable/checkmark"
            android:text="first" />
    
    </RelativeLayout>
    
    0 讨论(0)
提交回复
热议问题