1. Code
  2. Mobile Development
  3. Android Development

Creación de fondos de pantalla animados en Android

Scroll to top

Spanish (Español) translation by steven (you can also view the original English article)

Android tiene una serie de funciones de personalización para ayudar a los usuarios a personalizar muchos aspectos del dispositivo para mejorar la experiencia de usuario. Una de estas características es el fondo de pantalla animado. Los fondos de pantalla animados no permanecen como imágenes de fondo estáticas, sino que tienen funciones interactivas. ¡Aprende a crear un fondo de pantalla en vivo en este tutorial!

Un fondo de pantalla animado, en Android, se usa normalmente como fondo en la pantalla de inicio que se anima o cambia con el tiempo de alguna manera. Si tienes un dispositivo Android, probablemente hayas visto un par de fondos de pantalla en vivo incorporados, como aquel en el que las hojas parecen caer al agua y genera ondas.

Como desarrollador, puedes crear y publicar fondos de pantalla animados. El proceso no es particularmente difícil. Sin embargo, crear un fondo de pantalla animado que sea fascinante y deseable sin agotar la batería del dispositivo del usuario es un desafío. En este tutorial, te guiaremos a través del proceso de creación de un fondo de pantalla animado que se comporte. :)


Paso 0: Comenzando

Recientemente, te mostramos cómo usar RenderScript. El resultado final de ese tutorial fue un simple efecto de caída de nieve. Convirtamos ese efecto en un fondo de pantalla animado.

El código fuente abierto de este tutorial está disponible para descargar. Recomendamos usarlo para continuar. Los listados de código en este tutorial no incluyen el contenido completo de cada archivo y no cubren la configuración del proyecto o el código cubierto en tutoriales anteriores.


Paso 1: ¿Servicio o motor?

Se podría decir que un fondo de pantalla animado es solo un servicio. Después de todo, para crear un fondo de pantalla animado, simplemente se extiende desde la clase WallpaperService e implementa un método único, a menudo con una sola línea de código, y luego agrega su definición de servicio al archivo de manifiesto.

Veamos cómo se ve esto. Aquí está el WallpaperService:

1
public class FallingSnowWallpaperService extends WallpaperService {
2
    @Override
3
    public Engine onCreateEngine() {
4
        return new FallingSnowWallpaperEngine();
5
    }
6
}

¡Y ya acabaste! De acuerdo, en realidad no. La mayor parte del trabajo de un fondo de pantalla animado se lleva a cabo en una implementación de WallpaperService.Engine. Aquí es donde puede responder a devoluciones de llamada como onSurfaceChanged() y onSurfaceCreated(). ¿Te suena familiar? Estos son muy similares a las devoluciones de llamada que puedes haber visto al implementar una vista u otro objeto basado en Surface.

Y ahora se revela la realidad de los fondos de pantalla animados: al implementar WallpaperService.Engine, todo lo que estás haciendo es dibujar en una Surface proporcionada (a través de SurfaceHolder). Es casi así de simple. Antes de pasar a la implementación de WallpaperService.Engine, veamos algunos de los otros aspectos de la configuración.


Paso 2: Definición del fondo de pantalla

Dado que un fondo de pantalla animado es un servicio, debes registrar el servicio en tu archivo de manifiesto. El registro del servicio podría verse así:

1
        <service
2
            android:name="com.mamlambo.fallingsnow.FallingSnowWallpaperService"
3
            android:label="@string/app_name"
4
            android:permission="android.permission.BIND_WALLPAPER" >
5
            <intent-filter>
6
                <action android:name="android.service.wallpaper.WallpaperService" />
7
            </intent-filter>
8
            <meta-data
9
                android:name="android.service.wallpaper"
10
                android:resource="@xml/fallingsnow_wp" />
11
        </service>

Hay un par de cosas a tener en cuenta aquí. Primero, el uso de este servicio requiere el permiso BIND_WALLPAPER (es decir, otra aplicación que use este fondo de pantalla requeriría el permiso BIND_WALLPAPER como una entrada de permiso de uso en su manifiesto). En segundo lugar, el filtro de intención es una cadena similar a la clase base. Finalmente, los metadatos apuntan a un archivo XML. Este archivo XML, definido por el desarrollador, proporciona alguna configuración de fondo de pantalla adicional. Aquí está nuestro archivo XML para la configuración del fondo de pantalla aniado llamado fallingsnow_wp:

1
<?xml version="1.0" encoding="utf-8"?>
2
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
3
    android:thumbnail="@drawable/ic_launcher" 
4
    android:description="@string/fallingsnow_wp_desc" />

Aquí, simplemente usamos el icono del iniciador normal como miniatura y apuntamos a una cadena que aparecerá como descripción en la lista de fondos de pantalla. Si tu fondo de pantalla animado necesita configuración, lo señalará con la propiedad android:settingsActivity.

Android SDK - Live Wallpaper SettingsAndroid SDK - Live Wallpaper SettingsAndroid SDK - Live Wallpaper Settings

Finalmente, de vuelta en tu archivo de manifiesto, no olvides configurar la función de usos para android.software.live_wallpaper:

1
<uses-feature android:name="android.software.live_wallpaper" />

Paso 3: Estructura del motor de servicio del papel tapiz

Ahora que las cosas aburridas, pero críticas, están fuera del camino, regresemos al trabajo real: crear la clase WallpaperService.Engine. Como ya tenemos un archivo RenderScript para hacer algunas animaciones, todo lo que tenemos que hacer es vincular el renderizado a la nueva superficie. El método onSurfaceCreated() de Engine es un gran lugar para crear el objeto RenderScriptGL que necesitaremos:

1
        @Override
2
        public void onSurfaceCreated(SurfaceHolder holder) {
3
            super.onSurfaceCreated(holder);
4
            
5
            RenderScriptGL.SurfaceConfig surfaceConfig = new RenderScriptGL.SurfaceConfig();
6
            mRenderScriptGL = new RenderScriptGL(FallingSnowWallpaperService.this, surfaceConfig);
7
            
8
            // use low for wallpapers
9
            mRenderScriptGL.setPriority(RenderScript.Priority.LOW);
10
        }

También establecemos la prioridad de renderizado en baja: este es un fondo de pantalla animado y no un juego crítico o un motor de renderizado de UI. No debería ralentizar nada más en el sistema.

Limpia esto en el método onSurfaceDestroyed():

1
        @Override
2
        public void onSurfaceDestroyed(SurfaceHolder holder) {
3
            super.onSurfaceDestroyed(holder);
4
            if (mSnowRS != null)  {
5
                mSnowRS.stop();
6
                mSnowRS = null;
7
            }
8
            if (mRenderScriptGL != null) {
9
                mRenderScriptGL.destroy();
10
                mRenderScriptGL = null;
11
            }
12
        }

El método onSurfaceChanged() es un gran lugar para inicializar la clase RenderScript. Este es el primer lugar donde encontrarás los detalles de lo que vas a renderizar, como el ancho y el alto. Aquí también es donde configuramos la superficie para la clase RenderScriptGL.

1
        @Override
2
        public void onSurfaceChanged(SurfaceHolder holder, int format,
3
                int width, int height) {
4
            super.onSurfaceChanged(holder, format, width, height);
5
            
6
            
7
            if (mRenderScriptGL != null) {
8
                mRenderScriptGL.setSurface(holder, width, height);
9
            }
10
            if (mSnowRS == null) {
11
                mSnowRS = new SnowRS(width, height);
12
                mSnowRS.init(mRenderScriptGL, getResources(), isPreview());
13
                mSnowRS.start();
14
            } 
15
        }

Es una buena idea detener el papel tapiz cuando no sea visible.

1
        @Override
2
        public void onVisibilityChanged(boolean visible) {
3
            super.onVisibilityChanged(visible);
4
            if (mSnowRS == null) {
5
                if (visible) {
6
                    mSnowRS.start();
7
                } else {
8
                    mSnowRS.stop();
9
                }
10
            }

Y eso es. Rollos de papel tapiz en vivo. O animados. O hace lo que sea que quieras que haga.

¿Quieres responder a los toques? Anula el método onCommand() de la clase WallpaperService.Engine.

¿Quieres ajustar las posiciones cuando el usuario se desliza entre las páginas de la pantalla de inicio? Anula el método onOffsetsChanged() de la clase WallpaperService.Engine.

¿Quieres saber si el usuario está viendo la vista previa antes de configurar el fondo de pantalla? Llama al método isPreview() de la clase WallpaperService.Engine y verifica los resultados.

La implementación completa de nuestra clase WallpaperService.Engine se puede encontrar en FallSnowWallpaperService.java del proyecto de código abierto.

Echemos un vistazo al fondo de pantalla animado:

Android SDK - Live Wallpaper PreviewAndroid SDK - Live Wallpaper PreviewAndroid SDK - Live Wallpaper Preview

Eso debería parecer familiar; es lo mismo que vimos en la actividad de RenderScript.


Paso 4: Algunas notas sobre el rendimiento

Los fondos de pantalla animados son un gran lugar para crear efectos gráficos de gran eficacia y rendimiento. Pero debes hacerlo teniendo en cuenta que el usuario no está necesariamente sentado allí viendo una demostración (ya sabes, como los de scene.org). Lo que esto significa es que es posible que debas reducir la velocidad de fotogramas, reducir píxeles, recuentos de polígonos o detalles de textura para mantener el fondo de pantalla interesante, pero no estresante para la CPU, la GPU y la batería. Si los usuarios descubren que tu fondo de pantalla animado está consumiendo sus baterías, tu aplicación se verá muy mal y los dispositivos de esos usuarios se verán débiles con la poca batería que tienen. Una mala experiencia con un dispositivo Android hace que todos los desarrolladores sufran una mala reputación.


Paso 5: La vista previa

La vista previa y la actividad (del tutorial anterior) todavía están disponibles cuando se inicia la aplicación. En lugar de eliminarla, ¿por qué no simplemente agregar un controlador para que cuando un usuario haga clic en él, aparezca la configuración del fondo de pantalla animado para que el usuario pueda seleccionarlo?

1
    public void onWallpaperSettings(View view) {
2
        Intent wallpaperSettings = new Intent(Intent.ACTION_SET_WALLPAPER);
3
        startActivity(wallpaperSettings);
4
    }

¿Por qué no? Eso fue fácil. En cualquier vista en la que se pueda hacer clic, simplemente agrega la propiedad android:onClick="onWallpaperSettings" y listo.

Aquí hay una imagen fija:

Android SDK - Live Wallpaper PreviewAndroid SDK - Live Wallpaper PreviewAndroid SDK - Live Wallpaper Preview

Conclusión

Los fondos de pantalla animados son una forma conveniente de expandir tu aplicación más allá de sus límites típicos. ¿Tienes un juego de rol? Crea algunos fondos de pantalla animados con los personajes principales. Solo asegúrate de usar el sentido común al renderizar en la pantalla para que la experiencia del usuario con su dispositivo no se vea afectada.

¡Cuéntanos en los comentarios qué fondos de pantalla animados geniales estás creando!

Acerca de los autores

Los desarrolladores de dispositivos móviles Lauren Darcey y Shane Conder han sido coautores de varios libros sobre el desarrollo de Android: un libro de programación en profundidad titulado Desarrollo de aplicaciones inalámbricas de Android y Sams Teach Yourself Desarrollo de aplicaciones de Android en 24 horas. Cuando no están escribiendo, dedican su tiempo a desarrollar software móvil en su empresa y a brindar servicios de consultoría. Se les puede contactar por correo electrónico a androidwirelessdev+mt@gmail.com, a través de su blog en androidbook.blogspot.com y en Twitter @androidwireless.

¿Necesitas ayuda adicional para desarrollar aplicaciones de Android? ¡Revisa nuestros últimos libros y recursos!