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étodo | Descripció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Ãstica | RadioButton | CheckBox |
|---|---|---|
| Selección | Única | Múltiple |
| Agrupación | RadioGroup | Sin grupo |
| Deselección | Solo seleccionando otro | Click directo |
| Uso | Opciones excluyentes | Opciones independientes |
▶️ Cómo Ejecutar
- Abre Android Studio
- Crea el proyecto
- Copia el código
- Presiona Run
- 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