jueves, 25 de agosto de 2011

Elementos básicos del interface de usuario – RadioGroup y RadioButton - Basic elements of the user interface

Un RadioButton es un botón con un comportamiento similar al de un interruptor y puede tener dos estados : checked (encendido) o unchecked (apagado).
Normalmente se agrupan varios botones del tipo RadioButton dentro de un RadioGroup y, de este modo, cuando se enciende uno se apagan todos los demás pertenecientes al grupo.
RadioButton también desciende de TextView por lo que hereda todos los atributos que ya conocemos.
La definición en XML de un RadioGroup con varios RadioButton sería algo semejante a esto:

        <RadioGroup
           android:id="@+id/rgrup"
           android:orientation="horizontal"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           >
           <RadioButton
                 android:id="@+id/radio1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/item1"
             android:checked="false"
                 android:onClick="itemChecked">
           </RadioButton>
           <RadioButton
                 android:id="@+id/radio2"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/item2"
                 android:checked="false"
                 android:onClick="itemChecked">
           </RadioButton>
           <RadioButton
                 android:id="@+id/radio3"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/item3"
                 android:checked="false"
                 android:onClick="itemChecked">
           </RadioButton>
        </RadioGroup>
Como novedades vemos un atributo nuevo android:checked que puede tomar los valores “true” o “false”. Como podeis imaginar sirve para asignar un valor al RadioButton y que aparezca como encendido si tiene el valor true.

Al igual que con Button, podemos aplicar el atributo onClick para definir un método Java a ejecutar en el momento que se pulse sobre el RadioButton.
Podría ser algo así:


public class pruebaRadioButton extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    public void itemChecked (View v) {

        RadioButton item1 = (RadioButton) findViewById (R.id.radio1);
        RadioButton item2 = (RadioButton) findViewById (R.id.radio2);
        RadioButton item3 = (RadioButton) findViewById (R.id.radio3);
        TextView txtV2 = (TextView) findViewById (R.id.tv2);
    	
    	if (item1.isChecked()) txtV2.setBackgroundColor(Color.RED);
    	if (item2.isChecked()) txtV2.setBackgroundColor(Color.YELLOW);
    	if (item3.isChecked()) txtV2.setBackgroundColor(Color.GREEN);
    }
}

Como veis he definido un pequeño método público llamado itemChecked que recibe como parámetro un objeto  View y en él utilizo el método isChecked para comprobar el estado de cada RadioButton. En el caso de que estén activos cambio el atributo backgroundColor de un TextView definido en la vista. Por supuesto podriamos haber definido un método diferente para cada RadioButton en el XML.
 
Estado inicial

 
item3 checked
 
item2 checked

Hay varias maneras de conseguir este mismo objetivo. Una de ellas es asignar a cada RadioButton un listener desde Java y utilizar el método OnClick() para ejecutar las instrucciones que queramos.
En este caso debemos eliminar el atributo onClick en la definición de cada RadioButton en el archivo XML.
 


public class pruebaRadioButton extends Activity {
    /** Called when the activity is first created. */
	RadioButton item1;
	RadioButton item2;
	RadioButton item3;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        item1 = (RadioButton) findViewById (R.id.radio1);
        item2 = (RadioButton) findViewById (R.id.radio2);
        item3 = (RadioButton) findViewById (R.id.radio3);
        
        // Asigno el listener a cada RadioButton
        item1.setOnClickListener(myListener);
        item2.setOnClickListener(myListener);
        item3.setOnClickListener(myListener);
    }
    // Defino un listener y ejecuto el método itemChecked en onClick
    private OnClickListener myListener = new OnClickListener() {
        public void onClick(View v) {
            // Accion a realizar
            itemChecked();
        }
    };
    private void itemChecked () {

        TextView txtV2 = (TextView) findViewById (R.id.tv2);
    	
    	if (item1.isChecked()) txtV2.setBackgroundColor(Color.RED);
    	if (item2.isChecked()) txtV2.setBackgroundColor(Color.YELLOW);
    	if (item3.isChecked()) txtV2.setBackgroundColor(Color.GREEN);
    }
}


Como veis se define el listener myListener y en su método onClick() llamamos a la función itemChecked que en este caso no recibe ningún parámetro y puede ser privada.
Sólo nos falta asignar el listener a cada RadioGroup con setOnClickListener().


Otra forma de hacer esto mismo es definiendo un objeto Listener (OnCheckedChangeListener) y asignarlo al RadioGroup de manera que podamos controlar cada cambio de estado en cualquier elemento del grupo.

public class pruebaRadioButton extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        RadioGroup rGrup = (RadioGroup) findViewById (R.id.rgrup);
        
        // Defino el listener para el RadioGroup
        OnCheckedChangeListener listenerGrupo = 
            new OnCheckedChangeListener() {
            public void onCheckedChanged(RadioGroup group, int id) {
            	itemChecked (id);
            }
        };
        // Asigno el listener al RadioGroup
        rGrup.setOnCheckedChangeListener(listenerGrupo);
        
    }
    // Como parámetro recibe el id del item que ha cambiado su estado
    private void itemChecked (int id) {

        RadioButton item1 = (RadioButton) findViewById (R.id.radio1);
        RadioButton item2 = (RadioButton) findViewById (R.id.radio2);
        RadioButton item3 = (RadioButton) findViewById (R.id.radio3);
        TextView txtV2 = (TextView) findViewById (R.id.tv2);
    	
        // Compruebo si el id coincide con alguno de los RadioButton
    	if (item1.getId() == id) txtV2.setBackgroundColor(Color.RED);
    	if (item2.getId() == id) txtV2.setBackgroundColor(Color.YELLOW);
    	if (item3.getId() == id) txtV2.setBackgroundColor(Color.GREEN);
    }
}

En este caso también debemos eliminar el atributo onClick del XML puesto que el control de los estados lo haremos con el listener.
El listener recoge el id del elemento que ha variado su estado y se lo mandamos al método itemChecked para investigar de cual se trata y ejecutar el código correspondiente.


Para terminar os comentaré un par de métodos que me han parecido interesantes por su utilidad:
•    clearCheck() : Se utiliza para poner todos los elementos de un RadioGroup en estado de ‘unchecked’.
•    getCheckedRadioButtonId() : Se utiliza para conocer el id del RadioButton que en ese momento tiene estado ‘checked’

Por ejemplo:



RadioGroup rGrup = (RadioGroup) findViewById (R.id.rgrup);
// Leo el ID del RadioButton checked
int idRadio = rGroup.getCheckedRadioButtonId();
// Pongo todos los RadioButtons a unchecked
rGroup.clearCheck(); // 




1 comentario: