Mensajes emergentes en Android - Parte 1

En este post veremos el primero y más simple de los mensajes emergentes en Android. La plataforma Android nos proporciona mecanismos para crear de forma simple efectos muy integrados con la apariencia general del sistema.

Los mensajes que vamos a crear se denominan Toast y vamos a ver mensajes Toast de cuatro tipos:
Mensaje de sólo texto Mensaje con icono
Mensaje con icono y texto Mensaje con icono y texto con XML

Veamos cómo se crearía cada uno de ellos. Cabe destacar que este código debe ejecutarse dentro del código de una clase Activity.


Mensaje de sólo texto

Toast toast = Toast.makeText(getApplicationContext(), "Mensaje Toast con sólo texto", Toast.LENGTH_SHORT);
toast.show();


Mensaje con icono

Toast toast = new Toast(getApplicationContext());
ImageView view = new ImageView(getApplicationContext());
view.setImageResource(android.R.drawable.ic_menu_info_details);
toast.setView(view);
toast.setDuration(Toast.LENGTH_SHORT);
toast.show();


Mensaje con icono y texto

Toast toast = Toast.makeText(getApplicationContext(), "Mensaje Toast con texto e icono", Toast.LENGTH_SHORT);
View textView = toast.getView();
LinearLayout lay = new LinearLayout(getApplicationContext());
lay.setOrientation(LinearLayout.HORIZONTAL);
ImageView view = new ImageView(getApplicationContext());
view.setImageResource(android.R.drawable.ic_menu_info_details);
lay.addView(view);
lay.addView(textView);
toast.setView(lay);
toast.show();


Mensaje con icono y texto con XML

LayoutInflater inflater = getLayoutInflater();
View layoutView = inflater.inflate(layout, null);        
Toast toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_SHORT);
toast.setView(layoutView);
toast.show();

El código XML del Toast sería:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@layout/border"
    android:gravity="center">
        <ImageView 
              android:src="@android:drawable/ic_menu_info_details"
              android:layout_width="wrap_content"
              android:layout_height="fill_parent"
              android:layout_marginRight="10dp"/>
 <TextView 
             android:text="@string/text_icon_msg"
             android:layout_width="wrap_content"
             android:layout_height="fill_parent"
             android:textColor="#FFFFFF"
             android:gravity="center_vertical"/>
</LinearLayout>
Como puede verse, la propiedad android:background del elemento LinearLayout apunta a un layout llamado border. Este es una forma de hacer que la ventana tenga los bordes redondeados. Debemos crear un fichero XML llamado border.xml dentro de la carpeta res/layout con el siguiente contenido:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#444444"/>    
    <stroke 
        android:width="4dp" 
        android:color="#999999" />
    <padding 
        android:left="7dp" 
        android:top="7dp"
        android:right="7dp" 
        android:bottom="7dp" />
    <corners 
        android:bottomRightRadius="7dp" 
        android:bottomLeftRadius="7dp" 
        android:topLeftRadius="7dp" 
        android:topRightRadius="7dp"/> 
</shape> 

Ahora veamos el código de la clase activity al completo:
package org.ffbeltran;

import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

public class EjemploToast extends Activity {
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Button button;
        button = (Button) findViewById(R.id.text_only_button);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                textOnlyToast(getString(R.string.text_only_msg), Toast.LENGTH_SHORT);
            }
        });
        
        button = (Button) findViewById(R.id.icon_only_button);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                iconOnlyToast(android.R.drawable.ic_menu_info_details, Toast.LENGTH_SHORT);
            }
        });
        
        button = (Button) findViewById(R.id.text_icon_button);
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                textIconToast(R.layout.text_icon_toast, Toast.LENGTH_LONG);
//                textIconToast(getString(R.string.text_icon_msg), 
//                        android.R.drawable.ic_menu_info_details, Toast.LENGTH_SHORT);
            }
        });
    }
    
    private void textOnlyToast(String message, int duration) {
        Toast toast = Toast.makeText(getApplicationContext(), message, duration);
        toast.show();
    }
    
    private void iconOnlyToast(int icon, int duration) {
        Toast toast = new Toast(getApplicationContext());
        ImageView view = new ImageView(getApplicationContext());
        view.setImageResource(icon);
        toast.setView(view);
        toast.setDuration(duration);
        toast.show();
    }
    
    private void textIconToast(String message, int icon, int duration) {
        Toast toast = Toast.makeText(getApplicationContext(), message, duration);
        View textView = toast.getView();
        LinearLayout lay = new LinearLayout(getApplicationContext());
        lay.setOrientation(LinearLayout.HORIZONTAL);
        ImageView view = new ImageView(getApplicationContext());
        view.setImageResource(icon);
        lay.addView(view);
        lay.addView(textView);
        toast.setView(lay);
        toast.show();
    }
    
    private void textIconToast(int layout, int duration) {
        LayoutInflater inflater = getLayoutInflater();
        View layoutView = inflater.inflate(layout, null);        
        Toast toast = new Toast(getApplicationContext());
        toast.setDuration(duration);
        toast.setView(layoutView);
        toast.show();
    }
}
Éste es el código del layout principal:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal">
 <TextView  
     android:gravity="center"
  android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:text="@string/app_name"
     android:textSize="25sp"
     android:textStyle="bold"
        android:layout_marginTop="25dip"
     android:layout_marginBottom="25dip"/>
 <Button
     android:id="@id/text_only_button"
     android:layout_gravity="center"
     android:layout_width="200dip"
     android:layout_height="wrap_content"
     android:text="@string/text_only_button"/>
   <Button
     android:id="@id/icon_only_button"
     android:layout_gravity="center"
     android:layout_width="200dip"
     android:layout_height="wrap_content"
     android:text="@string/icon_only_button"/>
 <Button
     android:id="@id/text_icon_button"
     android:layout_gravity="center"
     android:layout_width="200dip"
     android:layout_height="wrap_content"
     android:text="@string/text_icon_button"/>
</LinearLayout>
Y éste el código de res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">EjemploToast</string>
    
    <string name="text_only_button">Sólo texto</string>
    <string name="icon_only_button">Sólo icono</string>
    <string name="text_icon_button">Texto e icono</string>
    
    <string name="text_only_msg">Mensaje Toast con sólo texto</string>
    <string name="text_icon_msg">Mensaje Toast con texto e icono</string>
</resources>
Por último, puedes cargar el código fuente aquí:

8 comentarios:

Anónimo dijo...

Muchisimas gracias!! me sirvio de gran ayuda :)

Un slaudo

Anónimo dijo...

Estaba buscando qué hacer para conseguir que las notificaciones se diesen según el idioma actual del móvil y con este tutorial lo he conseguido, simplemente modificando el string.xml (dependiendo del idioma pilla uno u otro).
Buen trabajo, un saludo!

Fede Fdez dijo...

Me alegra mucho que os sea útil. Gracias a los dos

Anónimo dijo...

Y para ponerle botones de aceptar o cancelar se puede o con que otra cosa se haria

Fede Fdez dijo...

Tendrías que hacerlo con un AlertDialog. Aquí hay un ejemplo: http://www.javaya.com.ar/androidya/detalleconcepto.php?codigo=165&inicio=20

zapo cabrera dijo...

Hola me ayudo mucho una duda abra alguna forma de darle al toast un tiempo definido pues quiero q aparesca y desaparesca rapidamente

Fede Fdez dijo...

Por desgracia sólo puedes elegir entre largo y corto, pasándole Toast.LENGTH_LONG o Toast.LENGTH_SHORT. Siempre puedes utilizar otra librería como crouton (https://github.com/keyboardsurfer/Crouton).

Saludos

luis alvarez dijo...

gracias por el aporte esta muy bien explicado :)

Publicar un comentario