Toast y Snackbar en Android

Toast y Snackbar en Android

Hola amigos 馃憢 Bienvenidos a un nuevo tutorial de Universo Android. Hoy aprenderemos a usar Toast y Snackbar, los componentes esenciales para mostrar mensajes temporales y notificaciones al usuario de forma elegante y efectiva.

Al finalizar este tutorial tendr谩s una aplicaci贸n que incluir谩:

  • Toast b谩sico y personalizado
  • Snackbar simple y con acciones
  • Diferentes duraciones y posiciones
  • Dise帽os personalizados
  • Mejores pr谩cticas de UX
  • Comparaci贸n entre Toast y Snackbar

馃煩 1. ¿Qu茅 es Toast y Snackbar?

Toast es un mensaje emergente temporal que aparece en la parte inferior de la pantalla y desaparece autom谩ticamente. No requiere interacci贸n del usuario.

Snackbar es similar pero m谩s vers谩til, pertenece a Material Design, puede incluir acciones y se muestra desde la parte inferior con animaci贸n.

馃煩 2. Diferencias Principales

Caracter铆sticaToastSnackbar
BibliotecaAndroid nativoMaterial Design
AccionesNoS铆
Posici贸nFija (inferior)Personalizable
Dise帽oB谩sicoMaterial Design
Interacci贸nSolo visualPuede tener botones

馃煩 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.9.0'
    implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
}

馃煩 5. Dise帽o XML Principal

馃搫 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        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="Toast y Snackbar Demo"
                android:textSize="24sp"
                android:textStyle="bold"
                android:textColor="#2196F3"
                android:layout_marginBottom="24dp" />

            <!-- Secci贸n Toast -->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Toast Examples"
                android:textSize="18sp"
                android:textStyle="bold"
                android:layout_marginBottom="16dp" />

            <Button
                android:id="@+id/btnToastShort"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Toast Short"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnToastLong"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Toast Long"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnToastCustom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Toast Personalizado"
                android:layout_marginBottom="8dp" />

            <!-- Separador -->
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#CCCCCC"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="16dp" />

            <!-- Secci贸n Snackbar -->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Snackbar Examples"
                android:textSize="18sp"
                android:textStyle="bold"
                android:layout_marginBottom="16dp" />

            <Button
                android:id="@+id/btnSnackbarShort"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Snackbar Short"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnSnackbarLong"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Snackbar Long"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnSnackbarIndefinite"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Snackbar Indefinido"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnSnackbarAction"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Snackbar con Acci贸n"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnSnackbarCustom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Snackbar Personalizado"
                android:layout_marginBottom="8dp" />

            <!-- Separador -->
            <View
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:background="#CCCCCC"
                android:layout_marginTop="16dp"
                android:layout_marginBottom="16dp" />

            <!-- Ejemplos Pr谩cticos -->
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Ejemplos Pr谩cticos"
                android:textSize="18sp"
                android:textStyle="bold"
                android:layout_marginBottom="16dp" />

            <Button
                android:id="@+id/btnDeleteExample"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Eliminar Item (con Undo)"
                android:backgroundTint="#F44336"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnSaveExample"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Guardar Datos"
                android:backgroundTint="#4CAF50"
                android:layout_marginBottom="8dp" />

            <Button
                android:id="@+id/btnErrorExample"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Mostrar Error"
                android:backgroundTint="#FF9800" />

        </LinearLayout>

    </ScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

馃煩 6. Layout Toast Personalizado

馃搫 res/layout/custom_toast.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="16dp"
    android:background="@drawable/toast_background"
    android:gravity="center_vertical">

    <ImageView
        android:id="@+id/toastIcon"
        android:layout_width="24dp"
        android:layout_height="24dp"
        android:src="@android:drawable/ic_dialog_info"
        android:tint="#FFFFFF" />

    <TextView
        android:id="@+id/toastText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Mensaje personalizado"
        android:textColor="#FFFFFF"
        android:textSize="16sp"
        android:layout_marginLeft="12dp" />

</LinearLayout>

馃煩 7. Drawable para Toast

馃搫 res/drawable/toast_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#323232" />
    <corners android:radius="16dp" />
    <padding android:left="16dp" android:top="12dp" 
             android:right="16dp" android:bottom="12dp" />
</shape>

馃煩 8. MainActivity

馃搫 MainActivity.java

import androidx.appcompat.app.AppCompatActivity;
import androidx.coordinatorlayout.widget.CoordinatorLayout;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;

public class MainActivity extends AppCompatActivity {

    CoordinatorLayout coordinatorLayout;
    Button btnToastShort, btnToastLong, btnToastCustom;
    Button btnSnackbarShort, btnSnackbarLong, btnSnackbarIndefinite;
    Button btnSnackbarAction, btnSnackbarCustom;
    Button btnDeleteExample, btnSaveExample, btnErrorExample;

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

        initializeViews();
        setupToastButtons();
        setupSnackbarButtons();
        setupExampleButtons();
    }

    private void initializeViews() {
        coordinatorLayout = findViewById(R.id.coordinatorLayout);
        
        btnToastShort = findViewById(R.id.btnToastShort);
        btnToastLong = findViewById(R.id.btnToastLong);
        btnToastCustom = findViewById(R.id.btnToastCustom);
        
        btnSnackbarShort = findViewById(R.id.btnSnackbarShort);
        btnSnackbarLong = findViewById(R.id.btnSnackbarLong);
        btnSnackbarIndefinite = findViewById(R.id.btnSnackbarIndefinite);
        btnSnackbarAction = findViewById(R.id.btnSnackbarAction);
        btnSnackbarCustom = findViewById(R.id.btnSnackbarCustom);
        
        btnDeleteExample = findViewById(R.id.btnDeleteExample);
        btnSaveExample = findViewById(R.id.btnSaveExample);
        btnErrorExample = findViewById(R.id.btnErrorExample);
    }

    private void setupToastButtons() {
        // Toast Short (2 segundos)
        btnToastShort.setOnClickListener(v -> 
            Toast.makeText(this, "Toast corto (2 segundos)", Toast.LENGTH_SHORT).show()
        );

        // Toast Long (3.5 segundos)
        btnToastLong.setOnClickListener(v -> 
            Toast.makeText(this, "Toast largo (3.5 segundos)", Toast.LENGTH_LONG).show()
        );

        // Toast Personalizado
        btnToastCustom.setOnClickListener(v -> showCustomToast());
    }

    private void setupSnackbarButtons() {
        // Snackbar Short
        btnSnackbarShort.setOnClickListener(v -> 
            Snackbar.make(coordinatorLayout, "Snackbar corto", Snackbar.LENGTH_SHORT).show()
        );

        // Snackbar Long
        btnSnackbarLong.setOnClickListener(v -> 
            Snackbar.make(coordinatorLayout, "Snackbar largo", Snackbar.LENGTH_LONG).show()
        );

        // Snackbar Indefinido
        btnSnackbarIndefinite.setOnClickListener(v -> {
            Snackbar snackbar = Snackbar.make(coordinatorLayout, 
                "Este Snackbar no desaparece autom谩ticamente", 
                Snackbar.LENGTH_INDEFINITE);
            snackbar.setAction("CERRAR", view -> snackbar.dismiss());
            snackbar.show();
        });

        // Snackbar con Acci贸n
        btnSnackbarAction.setOnClickListener(v -> {
            Snackbar snackbar = Snackbar.make(coordinatorLayout, 
                "Mensaje enviado", 
                Snackbar.LENGTH_LONG);
            snackbar.setAction("DESHACER", view -> 
                Toast.makeText(this, "Acci贸n deshecha", Toast.LENGTH_SHORT).show()
            );
            snackbar.setActionTextColor(Color.YELLOW);
            snackbar.show();
        });

        // Snackbar Personalizado
        btnSnackbarCustom.setOnClickListener(v -> showCustomSnackbar());
    }

    private void setupExampleButtons() {
        // Ejemplo: Eliminar con Undo
        btnDeleteExample.setOnClickListener(v -> {
            Snackbar snackbar = Snackbar.make(coordinatorLayout, 
                "Item eliminado", 
                Snackbar.LENGTH_LONG);
            snackbar.setAction("DESHACER", view -> 
                Toast.makeText(this, "Eliminaci贸n cancelada", Toast.LENGTH_SHORT).show()
            );
            snackbar.setActionTextColor(Color.parseColor("#FF5722"));
            snackbar.show();
        });

        // Ejemplo: Guardar exitoso
        btnSaveExample.setOnClickListener(v -> {
            Snackbar snackbar = Snackbar.make(coordinatorLayout, 
                "✓ Datos guardados exitosamente", 
                Snackbar.LENGTH_SHORT);
            snackbar.setBackgroundTint(Color.parseColor("#4CAF50"));
            snackbar.show();
        });

        // Ejemplo: Error
        btnErrorExample.setOnClickListener(v -> {
            Snackbar snackbar = Snackbar.make(coordinatorLayout, 
                "✗ Error al conectar con el servidor", 
                Snackbar.LENGTH_LONG);
            snackbar.setAction("REINTENTAR", view -> 
                Toast.makeText(this, "Reintentando...", Toast.LENGTH_SHORT).show()
            );
            snackbar.setBackgroundTint(Color.parseColor("#F44336"));
            snackbar.setActionTextColor(Color.WHITE);
            snackbar.show();
        });
    }

    private void showCustomToast() {
        LayoutInflater inflater = getLayoutInflater();
        View layout = inflater.inflate(R.layout.custom_toast, null);

        ImageView icon = layout.findViewById(R.id.toastIcon);
        TextView text = layout.findViewById(R.id.toastText);
        
        icon.setImageResource(android.R.drawable.ic_dialog_info);
        text.setText("Toast personalizado con icono");

        Toast toast = new Toast(getApplicationContext());
        toast.setDuration(Toast.LENGTH_LONG);
        toast.setView(layout);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }

    private void showCustomSnackbar() {
        Snackbar snackbar = Snackbar.make(coordinatorLayout, 
            "Snackbar personalizado", 
            Snackbar.LENGTH_LONG);
        
        // Personalizar colores
        snackbar.setBackgroundTint(Color.parseColor("#9C27B0"));
        snackbar.setTextColor(Color.WHITE);
        snackbar.setActionTextColor(Color.parseColor("#FFD700"));
        
        snackbar.setAction("VER", view -> 
            Toast.makeText(this, "Acci贸n ejecutada", Toast.LENGTH_SHORT).show()
        );
        
        snackbar.show();
    }
}

馃煩 9. M茅todos Principales de Toast

// Toast b谩sico
Toast.makeText(context, "Mensaje", Toast.LENGTH_SHORT).show();

// Toast con duraci贸n
Toast.LENGTH_SHORT  // 2 segundos
Toast.LENGTH_LONG   // 3.5 segundos

// Cambiar posici贸n
Toast toast = Toast.makeText(context, "Mensaje", Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP, 0, 100);
toast.show();

// Toast personalizado
Toast toast = new Toast(context);
toast.setView(customView);
toast.setDuration(Toast.LENGTH_LONG);
toast.show();

馃煩 10. M茅todos Principales de Snackbar

// Snackbar b谩sico
Snackbar.make(view, "Mensaje", Snackbar.LENGTH_SHORT).show();

// Con acci贸n
Snackbar.make(view, "Mensaje", Snackbar.LENGTH_LONG)
    .setAction("ACCI脫N", v -> {})
    .show();

// Personalizar colores
snackbar.setBackgroundTint(Color.RED);
snackbar.setTextColor(Color.WHITE);
snackbar.setActionTextColor(Color.YELLOW);

// Callback
snackbar.addCallback(new Snackbar.Callback() {
    @Override
    public void onShown(Snackbar sb) {
        // Cuando se muestra
    }
    
    @Override
    public void onDismissed(Snackbar sb, int event) {
        // Cuando se oculta
    }
});

馃煩 11. Duraciones de Snackbar

ConstanteDuraci贸n
LENGTH_SHORT1.5 segundos
LENGTH_LONG2.75 segundos
LENGTH_INDEFINITEHasta que se cierre

馃煩 12. Mejores Pr谩cticas

Cu谩ndo Usar Toast

✓ Mensajes informativos simples
✓ Confirmaciones sin importancia cr铆tica
✓ Feedback de operaciones completadas
✗ Errores importantes
✗ Acciones que requieren respuesta

Cu谩ndo Usar Snackbar

✓ Operaciones con opci贸n de deshacer
✓ Errores que requieren acci贸n
✓ Confirmaciones importantes
✓ Mensajes con contexto
✗ Mensajes muy frecuentes

馃煩 13. Clase Helper Reutilizable

馃搫 MessageHelper.java

import android.graphics.Color;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.snackbar.Snackbar;

public class MessageHelper {

    public static void showSuccess(View view, String message) {
        Snackbar snackbar = Snackbar.make(view, "✓ " + message, Snackbar.LENGTH_SHORT);
        snackbar.setBackgroundTint(Color.parseColor("#4CAF50"));
        snackbar.show();
    }

    public static void showError(View view, String message) {
        Snackbar snackbar = Snackbar.make(view, "✗ " + message, Snackbar.LENGTH_LONG);
        snackbar.setBackgroundTint(Color.parseColor("#F44336"));
        snackbar.show();
    }

    public static void showWarning(View view, String message) {
        Snackbar snackbar = Snackbar.make(view, "⚠ " + message, Snackbar.LENGTH_LONG);
        snackbar.setBackgroundTint(Color.parseColor("#FF9800"));
        snackbar.show();
    }

    public static void showInfo(View view, String message) {
        Snackbar snackbar = Snackbar.make(view, message, Snackbar.LENGTH_SHORT);
        snackbar.setBackgroundTint(Color.parseColor("#2196F3"));
        snackbar.show();
    }
}

▶️ C贸mo Ejecutar

  1. Abre Android Studio
  2. Presiona Run
  3. Prueba los diferentes botones
  4. Observa las diferencias entre Toast y Snackbar

馃И Resultado Final

Aplicaci贸n que muestra todos los tipos de Toast y Snackbar con ejemplos pr谩cticos de uso.

馃摜 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 Toast y Snackbar?
Toast es un mensaje simple sin interacci贸n. Snackbar es de Material Design, puede tener acciones y es m谩s personalizable.

2. ¿Puedo cambiar la posici贸n del Snackbar?
Snackbar siempre aparece en la parte inferior. Para otras posiciones usa Toast o crea un dise帽o personalizado.

3. ¿C贸mo hacer que Toast dure m谩s tiempo?
Toast solo permite LENGTH_SHORT y LENGTH_LONG. Para duraciones personalizadas considera usar Snackbar con LENGTH_INDEFINITE.

4. ¿Necesito CoordinatorLayout para Snackbar?
No es obligatorio, pero CoordinatorLayout permite que Snackbar interact煤e mejor con otros componentes como FloatingActionButton.

No hay comentarios:

Publicar un comentario