Blog para desarrollo de aplicaciones en Android, aprende paso a paso como crear aplicaciones.

RadioButton y RadioGroup en Android

RadioButton y RadioGroup en Android

Hola amigos 👋 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a usar RadioButton y RadioGroup, los componentes esenciales para crear opciones de selección única en formularios, encuestas y configuraciones de tu aplicación Android.

Al finalizar este tutorial tendrás:

  • RadioButton básico y avanzado
  • RadioGroup con selección única
  • Validación de selecciones
  • RadioButton personalizado
  • Material Design RadioButton
  • Eventos y listeners
  • Ejemplos prácticos completos

🟩 1. ¿Qué es RadioButton y RadioGroup?

RadioButton es un botón de selección única que permite elegir una opción de un conjunto. RadioGroup es el contenedor que agrupa RadioButtons asegurando que solo uno esté seleccionado a la vez.

🟩 2. Características Principales

  • Selección única automática
  • Estado visual claro (seleccionado/no seleccionado)
  • Agrupación lógica de opciones
  • Fácil validación de formularios
  • Compatible con Material Design

🟩 3. Crear el Proyecto

Creamos un nuevo proyecto en Android Studio con Empty Activity.

🟩 4. Agregar Dependencias

📄 build.gradle (Module: app)

dependencies {
    implementation 'androidx.appcompat:appcompat:1.6.1'
    implementation 'com.google.android.material:material:1.11.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
}

🟩 5. Diseño XML Principal

📄 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="RadioButton Demo"
            android:textSize="24sp"
            android:textStyle="bold"
            android:textColor="#2196F3"
            android:layout_marginBottom="24dp" />

        <!-- RadioGroup Básico -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Género:"
            android:textSize="18sp"
            android:textStyle="bold"
            android:layout_marginTop="8dp" />

        <RadioGroup
            android:id="@+id/radioGroupGender"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="8dp">

            <RadioButton
                android:id="@+id/radioMale"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Masculino"
                android:textSize="16sp"
                android:padding="8dp" />

            <RadioButton
                android:id="@+id/radioFemale"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Femenino"
                android:textSize="16sp"
                android:padding="8dp" />

            <RadioButton
                android:id="@+id/radioOther"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Otro"
                android:textSize="16sp"
                android:padding="8dp" />

        </RadioGroup>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#CCCCCC"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp" />

        <!-- RadioGroup Horizontal -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Tamaño:"
            android:textSize="18sp"
            android:textStyle="bold" />

        <RadioGroup
            android:id="@+id/radioGroupSize"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="8dp">

            <RadioButton
                android:id="@+id/radioSmall"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="S"
                android:layout_marginEnd="16dp" />

            <RadioButton
                android:id="@+id/radioMedium"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="M"
                android:checked="true"
                android:layout_marginEnd="16dp" />

            <RadioButton
                android:id="@+id/radioLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="L"
                android:layout_marginEnd="16dp" />

            <RadioButton
                android:id="@+id/radioXLarge"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="XL" />

        </RadioGroup>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#CCCCCC"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp" />

        <!-- RadioGroup con Tarjetas -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Plan de Suscripción:"
            android:textSize="18sp"
            android:textStyle="bold" />

        <RadioGroup
            android:id="@+id/radioGroupPlan"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="8dp">

            <!-- Plan Básico -->
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                app:cardCornerRadius="8dp"
                app:cardElevation="2dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:padding="16dp">

                    <RadioButton
                        android:id="@+id/radioBasic"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical" />

                    <LinearLayout
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:orientation="vertical"
                        android:layout_marginStart="12dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Plan Básico"
                            android:textSize="16sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Funciones básicas"
                            android:textSize="14sp"
                            android:textColor="#666666" />

                    </LinearLayout>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="$0/mes"
                        android:textSize="18sp"
                        android:textStyle="bold"
                        android:textColor="#4CAF50"
                        android:layout_gravity="center_vertical" />

                </LinearLayout>

            </androidx.cardview.widget.CardView>

            <!-- Plan Premium -->
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="8dp"
                app:cardCornerRadius="8dp"
                app:cardElevation="2dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal"
                    android:padding="16dp">

                    <RadioButton
                        android:id="@+id/radioPremium"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center_vertical" />

                    <LinearLayout
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:orientation="vertical"
                        android:layout_marginStart="12dp">

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Plan Premium"
                            android:textSize="16sp"
                            android:textStyle="bold" />

                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:text="Todas las funciones"
                            android:textSize="14sp"
                            android:textColor="#666666" />

                    </LinearLayout>

                    <TextView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="$9.99/mes"
                        android:textSize="18sp"
                        android:textStyle="bold"
                        android:textColor="#2196F3"
                        android:layout_gravity="center_vertical" />

                </LinearLayout>

            </androidx.cardview.widget.CardView>

        </RadioGroup>

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#CCCCCC"
            android:layout_marginTop="24dp"
            android:layout_marginBottom="24dp" />

        <!-- RadioGroup con Imágenes -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Método de Pago:"
            android:textSize="18sp"
            android:textStyle="bold" />

        <RadioGroup
            android:id="@+id/radioGroupPayment"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_marginTop="8dp">

            <RadioButton
                android:id="@+id/radioCard"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Tarjeta de Crédito/Débito"
                android:drawableStart="@android:drawable/ic_menu_gallery"
                android:drawablePadding="12dp"
                android:padding="12dp"
                android:background="?android:attr/selectableItemBackground" />

            <RadioButton
                android:id="@+id/radioPaypal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="PayPal"
                android:drawableStart="@android:drawable/ic_menu_send"
                android:drawablePadding="12dp"
                android:padding="12dp"
                android:background="?android:attr/selectableItemBackground" />

            <RadioButton
                android:id="@+id/radioCash"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Efectivo"
                android:drawableStart="@android:drawable/ic_menu_info_details"
                android:drawablePadding="12dp"
                android:padding="12dp"
                android:background="?android:attr/selectableItemBackground" />

        </RadioGroup>

        <!-- Botones de Acción -->
        <Button
            android:id="@+id/btnSubmit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Enviar Formulario"
            android:layout_marginTop="24dp" />

        <Button
            android:id="@+id/btnClear"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Limpiar Selección"
            android:backgroundTint="#FF9800"
            android:layout_marginTop="8dp" />

        <!-- Resultado -->
        <TextView
            android:id="@+id/txtResult"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="16dp"
            android:background="#F5F5F5"
            android:layout_marginTop="16dp"
            android:visibility="gone" />

    </LinearLayout>

</ScrollView>

🟩 6. MainActivity

📄 MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    RadioGroup radioGroupGender, radioGroupSize, radioGroupPlan, radioGroupPayment;
    RadioButton radioMale, radioFemale, radioOther;
    RadioButton radioSmall, radioMedium, radioLarge, radioXLarge;
    RadioButton radioBasic, radioPremium;
    RadioButton radioCard, radioPaypal, radioCash;
    Button btnSubmit, btnClear;
    TextView txtResult;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initializeViews();
        setupListeners();
    }

    private void initializeViews() {
        // RadioGroups
        radioGroupGender = findViewById(R.id.radioGroupGender);
        radioGroupSize = findViewById(R.id.radioGroupSize);
        radioGroupPlan = findViewById(R.id.radioGroupPlan);
        radioGroupPayment = findViewById(R.id.radioGroupPayment);

        // RadioButtons - Género
        radioMale = findViewById(R.id.radioMale);
        radioFemale = findViewById(R.id.radioFemale);
        radioOther = findViewById(R.id.radioOther);

        // RadioButtons - Tamaño
        radioSmall = findViewById(R.id.radioSmall);
        radioMedium = findViewById(R.id.radioMedium);
        radioLarge = findViewById(R.id.radioLarge);
        radioXLarge = findViewById(R.id.radioXLarge);

        // RadioButtons - Plan
        radioBasic = findViewById(R.id.radioBasic);
        radioPremium = findViewById(R.id.radioPremium);

        // RadioButtons - Pago
        radioCard = findViewById(R.id.radioCard);
        radioPaypal = findViewById(R.id.radioPaypal);
        radioCash = findViewById(R.id.radioCash);

        // Buttons y TextView
        btnSubmit = findViewById(R.id.btnSubmit);
        btnClear = findViewById(R.id.btnClear);
        txtResult = findViewById(R.id.txtResult);
    }

    private void setupListeners() {
        // Listener para RadioGroup Género
        radioGroupGender.setOnCheckedChangeListener((group, checkedId) -> {
            RadioButton selectedRadio = findViewById(checkedId);
            if (selectedRadio != null) {
                Toast.makeText(this, 
                    "Género: " + selectedRadio.getText(), 
                    Toast.LENGTH_SHORT).show();
            }
        });

        // Listener para RadioGroup Tamaño
        radioGroupSize.setOnCheckedChangeListener((group, checkedId) -> {
            RadioButton selectedRadio = findViewById(checkedId);
            if (selectedRadio != null) {
                Toast.makeText(this, 
                    "Tamaño: " + selectedRadio.getText(), 
                    Toast.LENGTH_SHORT).show();
            }
        });

        // Listener para RadioGroup Plan
        radioGroupPlan.setOnCheckedChangeListener((group, checkedId) -> {
            if (checkedId == R.id.radioBasic) {
                Toast.makeText(this, "Plan Básico seleccionado", Toast.LENGTH_SHORT).show();
            } else if (checkedId == R.id.radioPremium) {
                Toast.makeText(this, "Plan Premium seleccionado", Toast.LENGTH_SHORT).show();
            }
        });

        // Listener para RadioGroup Pago
        radioGroupPayment.setOnCheckedChangeListener((group, checkedId) -> {
            RadioButton selectedRadio = findViewById(checkedId);
            if (selectedRadio != null) {
                Toast.makeText(this, 
                    "Pago: " + selectedRadio.getText(), 
                    Toast.LENGTH_SHORT).show();
            }
        });

        // Botón Enviar
        btnSubmit.setOnClickListener(v -> submitForm());

        // Botón Limpiar
        btnClear.setOnClickListener(v -> clearSelections());
    }

    private void submitForm() {
        StringBuilder result = new StringBuilder();
        boolean isValid = true;

        // Validar Género
        int genderId = radioGroupGender.getCheckedRadioButtonId();
        if (genderId == -1) {
            result.append("❌ Selecciona un género\n");
            isValid = false;
        } else {
            RadioButton selectedGender = findViewById(genderId);
            result.append("✓ Género: ").append(selectedGender.getText()).append("\n");
        }

        // Validar Tamaño
        int sizeId = radioGroupSize.getCheckedRadioButtonId();
        if (sizeId == -1) {
            result.append("❌ Selecciona un tamaño\n");
            isValid = false;
        } else {
            RadioButton selectedSize = findViewById(sizeId);
            result.append("✓ Tamaño: ").append(selectedSize.getText()).append("\n");
        }

        // Validar Plan
        int planId = radioGroupPlan.getCheckedRadioButtonId();
        if (planId == -1) {
            result.append("❌ Selecciona un plan\n");
            isValid = false;
        } else {
            String planName = planId == R.id.radioBasic ? "Básico" : "Premium";
            result.append("✓ Plan: ").append(planName).append("\n");
        }

        // Validar Método de Pago
        int paymentId = radioGroupPayment.getCheckedRadioButtonId();
        if (paymentId == -1) {
            result.append("❌ Selecciona método de pago\n");
            isValid = false;
        } else {
            RadioButton selectedPayment = findViewById(paymentId);
            result.append("✓ Pago: ").append(selectedPayment.getText()).append("\n");
        }

        // Mostrar resultado
        txtResult.setVisibility(View.VISIBLE);
        
        if (isValid) {
            txtResult.setBackgroundColor(0xFFE8F5E9);
            txtResult.setTextColor(0xFF4CAF50);
            result.insert(0, "✅ Formulario Válido\n\n");
            Toast.makeText(this, "Formulario enviado correctamente", Toast.LENGTH_SHORT).show();
        } else {
            txtResult.setBackgroundColor(0xFFFFEBEE);
            txtResult.setTextColor(0xFFF44336);
            result.insert(0, "⚠️ Formulario Incompleto\n\n");
        }

        txtResult.setText(result.toString());
    }

    private void clearSelections() {
        radioGroupGender.clearCheck();
        radioGroupSize.clearCheck();
        radioGroupPlan.clearCheck();
        radioGroupPayment.clearCheck();
        txtResult.setVisibility(View.GONE);
        Toast.makeText(this, "Selecciones limpiadas", Toast.LENGTH_SHORT).show();
    }
}

🟩 7. RadioButton Personalizado

📄 res/drawable/radio_selector.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <!-- Estado seleccionado -->
    <item android:state_checked="true">
        <shape android:shape="oval">
            <solid android:color="#2196F3" />
            <size android:width="24dp" android:height="24dp" />
            <stroke android:width="2dp" android:color="#2196F3" />
        </shape>
    </item>
    
    <!-- Estado no seleccionado -->
    <item android:state_checked="false">
        <shape android:shape="oval">
            <solid android:color="#FFFFFF" />
            <size android:width="24dp" android:height="24dp" />
            <stroke android:width="2dp" android:color="#CCCCCC" />
        </shape>
    </item>
    
</selector>

Aplicar:

<RadioButton
    android:button="@drawable/radio_selector"
    android:text="Opción personalizada" />

🟩 8. Métodos Principales

MétodoDescripción
setChecked(boolean)Seleccionar RadioButton
isChecked()Verificar si está seleccionado
getCheckedRadioButtonId()Obtener ID del seleccionado
clearCheck()Limpiar selección
check(int)Seleccionar por ID
setOnCheckedChangeListener()Detectar cambios

🟩 9. Validación de RadioGroup

private boolean isRadioGroupSelected(RadioGroup radioGroup) {
    return radioGroup.getCheckedRadioButtonId() != -1;
}

private String getSelectedRadioText(RadioGroup radioGroup) {
    int selectedId = radioGroup.getCheckedRadioButtonId();
    if (selectedId != -1) {
        RadioButton radioButton = findViewById(selectedId);
        return radioButton.getText().toString();
    }
    return null;
}

🟩 10. RadioButton Dinámico

private void addRadioButtonDynamically(RadioGroup radioGroup, String text) {
    RadioButton radioButton = new RadioButton(this);
    radioButton.setText(text);
    radioButton.setTextSize(16);
    radioButton.setPadding(8, 8, 8, 8);
    
    RadioGroup.LayoutParams params = new RadioGroup.LayoutParams(
        RadioGroup.LayoutParams.WRAP_CONTENT,
        RadioGroup.LayoutParams.WRAP_CONTENT
    );
    radioButton.setLayoutParams(params);
    
    radioGroup.addView(radioButton);
}

🟩 11. Material RadioButton

<com.google.android.material.radiobutton.MaterialRadioButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Material Radio"
    app:buttonTint="#2196F3" />

🟩 12. Comparación CheckBox vs RadioButton

CaracterísticaRadioButtonCheckBox
SelecciónÚnicaMúltiple
AgrupaciónRadioGroupSin grupo
DeselecciónSolo seleccionando otroClick directo
UsoOpciones excluyentesOpciones independientes

▶️ Cómo Ejecutar

  1. Abre Android Studio
  2. Crea el proyecto
  3. Copia el código
  4. Presiona Run
  5. Prueba las diferentes opciones

🧪 Resultado Final

Aplicación con múltiples RadioGroups, validación completa y diferentes estilos de presentación.

📥 Descargar Proyecto

👉 

🙌 Gracias por Visitar mi Blog

✔️ Compártelo
✔️ Déjame un comentario
✔️ Sígueme para más contenido

❓ Preguntas Frecuentes

1. ¿Cuál es la diferencia entre RadioButton y CheckBox?
RadioButton permite selección única en un grupo. CheckBox permite múltiples selecciones independientes.

2. ¿Cómo deseleccionar un RadioButton?
Solo seleccionando otro RadioButton del mismo grupo, o usando clearCheck() en el RadioGroup.

3. ¿Puedo tener RadioButtons sin RadioGroup?
Sí, pero perderás la funcionalidad de selección única automática.

4. ¿Cómo valido que se haya seleccionado algo?
Verifica que getCheckedRadioButtonId() no retorne -1.

No hay comentarios:

Publicar un comentario