Más widgets y una app para verificar datos

Este es el segundo tutorial de la serie Fundamentos de Android con Java, aquí vamos a aprender más sobre el evento click y conocer algunos de los principales widgets más comunes en el desarrollo nativo Android. Como proyecto final crearemos una aplicación de una única pantalla donde verificaremos datos en diferentes widgets de Android utilizando Java.

Índice

  1. La unidad de medida en Android
  2. LinearLayout
  3. Relative Layout
  4. División proporcional
  5. Margin y Padding
  6. ScrollView
  7. EditText
  8. RadioButton y RadioGroup
  9. CheckBox
  10. Evento click usando listener
  11. Toast
  12. Tu turno
  13. El código

1. La unidad de medida en Android

Los dispositivos Android tienen distintas densidades de pixeles. No es raro que un celular de gama alta llegue hasta los 2K de resolución mientras que un gama baja puede tener alrededor de 720 x 1080 pixeles más o menos. Esto quiere decir que la cantidad de pixeles por pulgada cuadrada es distinta en diferentes dispositivos móviles.

Como ejemplo, aquí vemos tres cuadrados con ancho de 1 pulgada pero con distintas cantidades de pixeles. Vemos como 1 pixel puede ser de distinto tamaño dependiendo de la densidad de pixeles por pulgada.

Así que usar la unidad pixel en nuestros diseños nos mostraría diseños de distintos tamaños dependiendo del dispositivo. Por esta razón Android Studio tiene una unidad independiente a la densidad de pixeles por pulgada. Esta unidad se llama density independ pixel o dp.

Al usar esta unidad (dp) Android internamente mapea la pantalla del dispositivo asignando la cantidad de pixeles adecuada para que el diseño no sufra cambios a la vista del usuario de la aplicación.

2. LinearLayout

El LinearLayout es un widget de Android que nos permite agrupar widgets de manera vertical u horizontal en su interior. La dirección la podemos especificar usando el atributo android:orientatio. De este modo podemos colocar widgets uno sobre otro dentro de nuestra aplicación. El código XML base es el siguiente.

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">

    <!-- Widgets que queremos ordenar de manera vertical -->

</LinearLayout>

Además podríamos darle un color de fondo mediante el atributo android:background. En este atributo podemos colocar colores de la forma #FFFFFF o buscar algún color que tiene android usando la siguiente notación. @android:color/black.

3. Relative Layout

Este es un widget que nos permite agrupar otros widgets en su interior. La ventaja que tiene es que las posiciones de estos widgets las indicaremos de manera relativa a otros componentes, muy similar a la forma como indicamos la posición en un ConstraintLayout. El código XML base es el siguiente.

<RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

    <!--Otros elementos-->

</RelativeLayout>

4. División proporcional

Al tratar de ordenar estos widgets surge la duda de como dividir la pantalla en dos o tres partes iguales para colocar widgets dentro de cada una de estas partes en nuestra aplicación, o como hallar el centro para colocar un botón a cada lado.

Este problema se resuelve usando el atributo android:layout_weight. Usando este atributo podemos asignar un peso a cada elemento que este dentro de un LinearLayout. Este peso representa la proporción que queremos que ocupe nuestro widget dentro del LinearLayout. Pero, para que funcione correctamente la altura del widget debe ser igual a 0.

Por ejemplo, para dividir un LinearLayout en 3 partes iguales podemos hacer uso del atributo android:layout_weight de la siguiente manera.

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/darker_gray"
        android:layout_weight="1"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_orange_dark"
        android:layout_weight="1"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_green_light"
        android:layout_weight="1"/>

</LinearLayout>

La suma total de los pesos conforma el total del contenedor, mientras que las proporciones se dividen conforme el peso de cada widget. En el ejemplo anterior el total es 3 y cada widget tiene un peso proporcional a 1 de 3

Ahora si lo que queremos es excluir en esta división proporcional a algún elemento solo bastaría con no darle la propiedad layout_weight a ese elemento y darle un layout_height determinado. Como en el siguiente ejemplo.

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/darker_gray" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/black" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_orange_dark"
        android:layout_weight="1"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_green_light"
        android:layout_weight="1"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        android:layout_weight="1"/>

</LinearLayout>

Por ultimo, existe una forma de rellenar todo el espacio disponible en un LinearLayout generalmente después de tener varios elementos con tamaño definido. Para lograr esto el componente que rellenará el espacio sobrante debe tener un layout_height igual a 0 y layout_weight igual a 1. Veamos el siguiente ejemplo.

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

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@android:color/holo_blue_light"
        android:layout_weight="1"/>
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/darker_gray" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="@android:color/black" />

</LinearLayout>

5. Margin y Padding

Tanto marging y padding son atributos que se puedes colocar a cualquier widget dentro de Android. La propiedad android:layout_margin lo usamos para indicar la distancia de separación entre nuestro componente y otros componentes cerca de él. Mientras que android:padding lo utilizamos para indicar el tamaño del borde de nuestro componente.

6. ScrollView

Es un widget de Android que agrupa widgets en su interior con la característica de que podemos hacer scroll entre esos elementos. Generalmente dentro de este widget se utiliza un LinearLayout para ordenar los elementos de manera vertical y hacer scroll cuando este tiene más elementos de los que puedan salir en pantalla.

<ScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="25dp">

    <!-- Linear Layout -->

</ScrollView>

7. EditText

Este widget nos sirve para obtener algún dato escrito del usuario. Es muy utilizado en las interfaces de usuario para pedir el usuario y contraseña en un login por ejemplo.

<EditText
    android:id="@+id/txt_name"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
Recuerda que a los widgets con los que interactuaremos desde el código Java o Kotlin ya sea para obtener su valor o capturar algún evento debemos colocarle un atributo id para identificarlos desde el código Java o Kotlin.

La forma de obtener el valor que el usuario escribió en un TextView es usando el método getText() luego de haber identificado el widget como en el siguiente ejemplo de código.

public class MainActivity extends AppCompatActivity {

    // Declaramos la variable para nuestro EditText
    private EditText edt_name;
    // Declaramos la variable que recibira el contenido del EditText
    private String name;

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

        // Enlazamos el EditText creado aqui con el Widget de la interface mediante el Id
        edt_name = findViewById(R.id.edt_name);

    }
    // Creamos una funcion que obtenga el valor del EditText.
    // Esta funcion puede ser ejecutada por ejemplo al hacer click a un botón
    public void obtnerName(){
        name = edt_name.getText().toString();
    }
}

También tenemos una forma de mostrar un error al usuario. Quizá cuando escribio mal o no puso valor alguno en un campo de texto necesario. Para lograr esto usamos el método setError(). Lo adecuado es colocar este método dentro de alguna estructura If que verifique primero el valor escrito en el EditText.

edt_name.setError("Complete name");

8. RadioButton y RadioGroup

RadioButton es el widget que permite al usuario seleccionar una única opción de un conjunto de opciones. es muy común e interfaces de usuario y seguramente ya lo vieron alguna vez, tiene la siguiente apariencia.

Este widget para que nos permita seleccionar solo un RadioButton de entre varios, todos deben estar dentro de un mismo RadioGroup como en el siguiente código.

<RadioGroup
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:orientation="horizontal">

    <RadioButton
        android:id="@+id/rbt_male"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Male"
        android:textSize="18dp" />

    <RadioButton
        android:id="@+id/rbt_female"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Female"
        android:textSize="18dp" />

</RadioGroup>

La forma de obtener el valor de un RadioButton en Java es la siguiente.

// Luego de declara el RadioButton rbt_male obtenemos su valor así
Boolean checked = rbt_male.isChecked()

9. CheckBox

Este widget nos permite seleccionar uno o más opciones de un conjunto de opciones. Seguramente también lo vieron alguna vez ya que es muy común.

<CheckBox
    android:id="@+id/chk_mathematics"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dp"
    android:text="Mathematics"
    android:textSize="18dp" />

Obtenemos su valor desde Java de la siguiente forma.

// Luego de declara el CheckBox chk_technology obtenemos su valor así
Boolean checked = chk_technology.isChecked();

10. Evento click usando listener

Un listener, como su nombre lo indica, es un escuchador que nos permite escuchar eventos que suceden dentro de nuestra aplicación. En este caso lo usaremos para escuchar el evento de click en un botón. Para esto usamos el método setOnClickListener() que nos permite escuchar el evento click dentro de algún widget en Java.

private Button btn_send;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Enlazando el objeto btn_send con el boton de la interface
    btn_send = findViewById(R.id.btn_send);

    btn_send.setOnClickListener();
}

El parámetro que recibe este método es un objeto que implemente de una interface específica llamada View.OnClickListener. Así que debemos crear una clase de este tipo dentro de nuestra clase MainActivity.

class ejecutar implements View.OnClickListener{
    // onClick es un método que necesariamente se debe sobreescribir al implementar View.OnClickListener
    @Override
    public void onClick(View v) {
        // Código a ejecutar
    }
}

Entonces el objeto de esta clase es el que le pasaremos al método setOnClickListener() del botón.

btn_send.setOnClickListener(new ejecutar());

Otra forma de crear un listener es definiendo la clase dentro de los paréntesis del parámetro del método setOnClickListener(). De esta forma no necesitamos crear otra clase y todo lo podemos definir dentro del método onCreate().

widget.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Aqui lo que ejecutará nuestro botón.
    }
});

11. Toast

El toast es un widget de Android que podemos utilizar para mostrar un mensaje en la pantalla, pero por un corto periodo de tiempo.

Los pasos para crear un Toast son los siguientes.

public class MainActivity extends AppCompatActivity {
    // Declarando el objeto Toast
    private Toast message;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // Creando el mensaje para el Toast
        message = Toast.makeText(MainActivity.this, "Mensaje", Toast.LENGTH_SHORT);
    }
    // Método que muestra el Toast
    public void mostrarToas(){
        message.show();
    }
}

12. Tu turno

Usando estos conceptos que acabamos de aprender de Android te animo a realizar el siguiente proyecto. Una aplicación para validar datos de una sola pantalla utilizando todos los widgets que aprendimos en este tutorial.

Cuando quieras puedes ver el código del proyecto terminado. Pero ándale inténtalo tu mismo!!

13. El código

El código del proyecto está en el siguiente repositorio github.com/andygeek/VerifyingDataJava