Android: ¿Cómo obtener un radiogrupo con botones de selección?

Quiero un grupo de botones donde un usuario puede elegir uno de ellos como opción. Tiene que ser un radiobuttongroup como comportamiento, pero no quiero que el círculo de radio esté presente. Sólo quiero que el usuario sea capaz de alternar sólo uno de los botones.

Creo que necesitaría algo como un grupo de toggle.

¿Existe algo como esto en Android?

Me gustaría volver a usar el RadioGroup así: (tenga en cuenta el atributo onClick, es decir, un clic de botón activará el método onToggle (View) de su actividad.

<RadioGroup android:id="@+id/toggleGroup" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="24dp" android:orientation="horizontal" > <ToggleButton android:id="@+id/btn_Letter" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1" android:textSize="14sp" android:textOn="Letter" android:textOff="Letter" android:onClick="onToggle" android:checked="true" /> <ToggleButton android:id="@+id/btn_A4" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1" android:textSize="14sp" android:textOn="A4" android:textOff="A4" android:onClick="onToggle" /> </RadioGroup> 

En su actividad, o en otro lugar, puede definir un oyente, por ejemplo

 static final RadioGroup.OnCheckedChangeListener ToggleListener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(final RadioGroup radioGroup, final int i) { for (int j = 0; j < radioGroup.getChildCount(); j++) { final ToggleButton view = (ToggleButton) radioGroup.getChildAt(j); view.setChecked(view.getId() == i); } } }; 

Y registrarlo, por ejemplo en onCreate ():

  @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.scan_settings); ((RadioGroup) findViewById(R.id.toggleGroup)).setOnCheckedChangeListener(ToggleListener); } 

Finalmente en onToggle (View), haría lo que fuera necesario, específico de su aplicación. Y también llamar al método de verificación de RadioGroup, con el ID de la vista alternada. Al igual que:

 public void onToggle(View view) { ((RadioGroup)view.getParent()).check(view.getId()); // app specific stuff .. } 

Puede utilizar los botones de radio normales y utilizar una imagen para el fondo de RadioButton y no especificar una cadena de texto:

 <RadioButton android:id="@+id/custom_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:button="@null" android:background="@drawable/button_custom" /> 

Para el fondo, utilice cualquier dibujable, pero lo más probable es que desee utilizar un selector para poder proporcionar imágenes diferentes para los diferentes estados. La versión más sencilla utiliza sólo dos imágenes:

 <item android:state_checked="true" android:state_pressed="true" android:drawable="@drawable/custom_selected" /> <item android:state_checked="false" android:state_pressed="true" android:drawable="@drawable/custom_normal" /> <item android:state_checked="true" android:state_focused="true" android:drawable="@drawable/custom_selected" /> <item android:state_checked="false" android:state_focused="true" android:drawable="@drawable/custom_normal" /> <item android:state_checked="false" android:drawable="@drawable/custom_normal" /> <item android:state_checked="true" android:drawable="@drawable/custom_selected" /> 

Con esto, el botón de radio se parece a un botón regular (o mejor dicho, se ve como cualquier dibujable proporcionado) y se comporta como un botón de radio en un grupo de radio.

He intentado todos los métodos descritos anteriormente y ninguno realmente funcionó tan bien.

Tratar de cortar un botón de radio para que parezca un botón real se ve mal.

Eventualmente acabo de tomar el código fuente de RadioGroup y modificarlo para aceptar un ToggleButton en lugar de un RadioButton. Funciona muy bien!

Esta es la fuente en Github: ToggleGroup

Uso:

  <com.rapsacnz.ToggleGroup android:id="@+id/deal_detail_toolbar" android:layout_width="fill_parent" android:layout_height="60dip" android:layout_alignParentBottom="true" android:background="@drawable/bgnd_toggle_button"> <ToggleButton android:id="@+id/b1" android:textOn="@string/tab_1_label" android:textOff="@string/tab_1_label" android:textSize="10sp" android:textColor="@color/tab_button_color" android:checked="true" android:layout_width="fill_parent" android:layout_height="60dp" android:layout_weight="1" android:drawableTop="@drawable/toggle_spotlight" android:drawablePadding="-5dp " android:gravity="bottom|center" android:paddingTop="10dp" android:paddingBottom="5dp" android:background="@drawable/bgnd_transparent" /> <ToggleButton android:id="@+id/b2" android:textOn="@string/tab_2_label" android:textOff="@string/tab_2_label" android:textSize="10sp" android:textColor="@color/tab_button_color" android:checked="false" android:layout_width="fill_parent" android:layout_height="60dp" android:layout_weight="1" android:drawableTop="@drawable/toggle_browse" android:gravity="bottom|center" android:paddingTop="10dp" android:paddingBottom="5dp" android:background="@drawable/bgnd_transparent" /> <ToggleButton android:id="@+id/b3" android:textOn="@string/tab_3_label" android:textOff="@string/tab_3_label" android:textSize="10sp" android:textColor="@color/tab_button_color" android:checked="false" android:layout_width="fill_parent" android:layout_height="60dp" android:layout_weight="1" android:drawableTop="@drawable/toggle_purchased" android:gravity="bottom|center" android:paddingTop="10dp" android:paddingBottom="5dp" android:background="@drawable/bgnd_transparent" /> </com.rapsacnz.ToggleGroup> 

Espero que esto ayude

He aquí cómo me las arreglé para hacerlo (sin RadioGroup involucrado):

 private CompoundButton.OnCheckedChangeListener toggleListener = new CompoundButton.OnCheckedChangeListener() { boolean avoidRecursions = false; @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(avoidRecursions) return; avoidRecursions = true; // don't allow the un-checking if(!isChecked) { buttonView.setChecked(true); avoidRecursions = false; return; } // un-check the previous checked button if(buttonView != toggleButton1 && toggleButton1.isChecked()) toggleButton1.setChecked(false); else if(buttonView != toggleButton2 && toggleButton2.isChecked()) toggleButton2.setChecked(false); else if(buttonView != toggleButton3 && toggleButton3.isChecked()) toggleButton3.setChecked(false); else if(buttonView != toggleButton4 && toggleButton4.isChecked()) toggleButton4.setChecked(false); avoidRecursions = false; } }; // ... toggleButton1.setOnCheckedChangeListener(toggleListener); toggleButton2.setOnCheckedChangeListener(toggleListener); toggleButton3.setOnCheckedChangeListener(toggleListener); toggleButton4.setOnCheckedChangeListener(toggleListener); 

Mi solución logra el mismo efecto pero sin usar los radiobotones.

Para el xml, primero un "selector" en "@ drawable / myselectorfile":

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

Un archivo para los elementos de mi listview:

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/txtInfo" android:layout_width="140dp" android:layout_height="wrap_content" android:paddingTop="15dip" /> <ToggleButton android:id="@+id/BtnToggle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="14dp" android:background="@drawable/toggle_style" android:padding="10dip" android:textOff="" android:textOn="" android:focusable="false"/> </LinearLayout> 

Y mi lista:

  <?xml version="1.0" encoding="utf-8"?> <ListView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/lv_lista" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView> 

En el método de crianza:

  lista.setOnItemClickListener(new OnItemClickListener() { @SuppressWarnings("deprecation") @Override public void onItemClick(AdapterView<?> pariente, View view, int posicion, long id) { @SuppressWarnings("unused") ListEntity elegido = (ListEntity) pariente.getItemAtPosition(posicion); varToggle = (ToggleButton) view.findViewById(R.id.BtnToggle); varToggle.setChecked(true); // showDialog(0); // dialog optional //restart btn's reStart(posicion); } }); 

En la clase de actividad:

  @Override protected Dialog onCreateDialog(int id){ Dialog dialogo = crearDialogoConfirmacion(); return dialogo; } public void reStart(int posicion){ for(int j=0;j<lista.getCount();j++) { View vista = lista.getChildAt(j); ToggleButton varToggle2 = (ToggleButton) vista.findViewById(R.id.BtnToggle); if(j != posicion){ varToggle2.setChecked(false); } } } 

¿Así que desea botones de que sólo uno puede ser seleccionado a la vez? Si no muestra el botón de radio, ¿cómo sabe el usuario lo que ha seleccionado?

Usted puede trabajar con RadioButton y RadioGroup pero no sé si fácilmente puede generar un botón de radio personalizado con un aspecto más adecuado a su aplicación. Pero debería ser posible de alguna manera si se puede extender el radiobutton en sí y anular el método de dibujo, o ver qué niño de botones se pueden integrar en un radiogrupo . Tal vez usted puede implementar una interfaz especial para su vista y luego unirse a algunos de sus botones personalizados juntos en un radiogrupo.

Lo hice con LinearLayout en vez de RadioGroup, usando ButterKnife:

 @BindViews({R.id.one, R.id.two, R.id.three}) List<ToggleButton> mToggleGroup; @Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { ButterKnife.bind(this, view); } @OnClick({R.id.one, R.id.two, R.id.three}) public void toggle(ToggleButton selected) { if (selected.isChecked()) { // Deselect other buttons for (ToggleButton button : mToggleGroup) { if (button.getId() != selected.getId()) { button.setChecked(false); } } } else { // Disallow deselecting the current button selected.toggle(); } } 

Utilizando cualquier contenedor ViewGroup agregue sus CompoundButtons (CheckBox, RadioButton, Switch, SwitchCompat, ToggleButton) y luego dentro de su onCheckedChanged llame a una función de utilidad para borrar los otros botones.

  <LinearLayout android:id="@+id/toggle_group" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ToggleButton android:id="@+id/toggle_btn1" android:layout_width="wrap_content" android:layout_height="match_parent" android:textOff="Off1" android:textOn="On1" /> <View android:layout_width="2dp" android:layout_height="match_parent" android:layout_margin ="8dp" android:background="#ffff" /> <ToggleButton android:id="@+id/toggle_btn2" android:layout_width="wrap_content" android:layout_height="match_parent" android:textOff="Off2" android:textOn="On2" /> </LinearLayout> 

Dentro de su onCheckedChanged , tratar con el cambio de estado y llamar al método de utilidad para borrar a los otros niños. Lo siguiente es compatible con todos los grupos de contenedores de vista que se derivan de ViewGroup y le permite mezclar objetos no CompoundButton en el contenedor. Ya que a menudo tiene una devolución de llamada onCheckedChanged ya, sólo nuevo código es llamar a la función de utilidad.

 @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { int id = buttonView.getId(); switch (id) { case R.id.toggle_btn1: if (isChecked) { doBtn1Action(); doRadioGroupChange((ViewGroup)buttonView.getParent(), id); } break; case R.id.toggle_btn2: if (isChecked) { doBtn2Action();; doRadioGroupChange((ViewGroup)buttonView.getParent(), id); } break; 

Y aquí está la función de utilidad para limpiar a los niños.

 /** * Emulate radioGroup and clear buttons which don't match checkedId. * @param viewGroup * @param checkedId */ private static void doRadioGroupChange(final ViewGroup viewGroup, final int checkedId) { for (int rgIdx = 0; rgIdx < viewGroup.getChildCount(); rgIdx++) { View child = viewGroup.getChildAt(rgIdx); if (child instanceof CompoundButton) { final CompoundButton view = (CompoundButton) viewGroup.getChildAt(rgIdx); view.setChecked(view.getId() == checkedId); } } } 
FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.