300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android动态壁纸的制作教程

Android动态壁纸的制作教程

时间:2024-05-02 13:28:43

相关推荐

Android动态壁纸的制作教程

动态壁纸是在Android 2.1新增的一个功能。动态壁纸可以添加到Android的桌面,具有交互式的动画背景效果。在本教程中,我们将教会你如何去制作一个交互式的动态壁纸。

动态壁纸是一个Android应用程序,包括一个服务(WallpaperService )。该服务必须包括一个引擎(WallpaperService.Engine )。该引擎是连接用户、桌面、系统之间的桥梁。它也可以绘制桌面壁纸。

首先,必须由内在的Engine类创建一个WallpaperService类。该服务必须在AndroidManifest.xml中声明 为"android.service.wallpaper.WallpaperService",这样它才会作为动态壁纸被手机识别。而且还要在服务配置 中附加"android.permission.BIND_WALLPAPER"的权限许可:

<serviceandroid:name="LiveWallpaperService"android:enabled="true"android:icon="@drawable/icon"android:label="@string/app_name"android:permission="android.permission.BIND_WALLPAPER"><intent-filter android:priority="1" ><action android:name="android.service.wallpaper.WallpaperService" /></intent-filter><meta-dataandroid:name="android.service.wallpaper"android:resource="@xml/wallpaper" /></service>

创建一个XML文件,放置在应用程序目录下的/res/xml/中。它用来描述你的动态壁纸。

<?xml version="1.0" encoding="UTF-8"?><wallpaperxmlns:android="/apk/res/android "android:thumbnail="@drawable/thumbnail"android:description="@string/description"android:settingsActivity="PreferenceActivity"/>

再创建一个xml的属性文件attrs.xml,代码如下:

<declare-styleable name="Wallpaper"><!-- Component name of an activity that allows the user to modifythe current settings for this wallpaper. --><attr name="settingsActivity" /><!-- Reference to a the wallpaper's thumbnail bitmap. --><attr name="thumbnail" format="reference" /><!-- Name of the author of this component, e.g. Google. --><attr name="author" format="reference" /><!-- Short description of the component's purpose or behavior. --><attr name="description" /></declare-styleable>

动态壁纸的服务代码如下:

package net.androgames.blog.sample.livewallpaper;import android.content.SharedPreferences;import android.service.wallpaper.WallpaperService;import android.view.MotionEvent;import android.view.SurfaceHolder;/*** Android Live Wallpaper Archetype* @author antoine vianey* under GPL v3 : /licenses/gpl-3.0.html*/public class LiveWallpaperService extends WallpaperService {@Overridepublic Engine onCreateEngine() {return new SampleEngine();}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}public class SampleEngine extends Engine {private LiveWallpaperPainting painting;SampleEngine() {SurfaceHolder holder = getSurfaceHolder();painting = new LiveWallpaperPainting(holder,getApplicationContext());}@Overridepublic void onCreate(SurfaceHolder surfaceHolder) {super.onCreate(surfaceHolder);// register listeners and callbacks heresetTouchEventsEnabled(true);}@Overridepublic void onDestroy() {super.onDestroy();// remove listeners and callbacks herepainting.stopPainting();}@Overridepublic void onVisibilityChanged(boolean visible) {if (visible) {// register listeners and callbacks herepainting.resumePainting();} else {// remove listeners and callbacks herepainting.pausePainting();}}@Overridepublic void onSurfaceChanged(SurfaceHolder holder, int format,int width, int height) {super.onSurfaceChanged(holder, format, width, height);painting.setSurfaceSize(width, height);}@Overridepublic void onSurfaceCreated(SurfaceHolder holder) {super.onSurfaceCreated(holder);// start paintingpainting.start();}@Overridepublic void onSurfaceDestroyed(SurfaceHolder holder) {super.onSurfaceDestroyed(holder);boolean retry = true;painting.stopPainting();while (retry) {try {painting.join();retry = false;} catch (InterruptedException e) {}}}@Overridepublic void onOffsetsChanged(float xOffset, float yOffset,float xStep, float yStep, int xPixels, int yPixels) {}@Overridepublic void onTouchEvent(MotionEvent event) {super.onTouchEvent(event);painting.doTouchEvent(event);}}}

当壁纸的显示、状态或大小变化是,会调用Engine的onCreate,onDestroy,onVisibilityChanged,onSurfaceChanged,onSurfaceCreatedonSurfaceDestroyed方法。有了这些方法,动态壁纸才能展现出动画效果。而通过设置setTouchEventsEnabled(true),并且调用onTouchEvent(MotionEvent event)方法,来激活触摸事件。

我们在绘画墙纸的时候,也会使用一个单独的绘画线程:

package net.androgames.blog.sample.livewallpaper;import android.content.Context;import android.graphics.Canvas;import android.view.MotionEvent;import android.view.SurfaceHolder;/*** Android Live Wallpaper painting thread Archetype* @author antoine vianey* GPL v3 : /licenses/gpl-3.0.html*/public class LiveWallpaperPainting extends Thread {/** Reference to the View and the context */private SurfaceHolder surfaceHolder;private Context context;/** State */private boolean wait;private boolean run;/** Dimensions */private int width;private int height;/** Time tracking */private long previousTime;private long currentTime;public LiveWallpaperPainting(SurfaceHolder surfaceHolder,Context context) {// keep a reference of the context and the surface// the context is needed if you want to inflate// some resources from your livewallpaper .apkthis.surfaceHolder = surfaceHolder;this.context = context;// don't animate until surface is created and displayedthis.wait = true;}/*** Pauses the live wallpaper animation*/public void pausePainting() {this.wait = true;synchronized(this) {this.notify();}}/*** Resume the live wallpaper animation*/public void resumePainting() {this.wait = false;synchronized(this) {this.notify();}}/*** Stop the live wallpaper animation*/public void stopPainting() {this.run = false;synchronized(this) {this.notify();}}@Overridepublic void run() {this.run = true;Canvas c = null;while (run) {try {c = this.surfaceHolder.lockCanvas(null);synchronized (this.surfaceHolder) {currentTime = System.currentTimeMillis();updatePhysics();doDraw(c);previousTime = currentTime;}} finally {if (c != null) {this.surfaceHolder.unlockCanvasAndPost(c);}}// pause if no need to animatesynchronized (this) {if (wait) {try {wait();} catch (Exception e) {}}}}}/*** Invoke when the surface dimension change*/public void setSurfaceSize(int width, int height) {this.width = width;this.height = height;synchronized(this) {this.notify();}}/*** Invoke while the screen is touched*/public void doTouchEvent(MotionEvent event) {// handle the event here// if there is something to animate// then wake upthis.wait = false;synchronized(this) {notify();}}/*** Do the actual drawing stuff*/private void doDraw(Canvas canvas) {}/*** Update the animation, sprites or whatever.* If there is nothing to animate set the wait* attribute of the thread to true*/private void updatePhysics() {// if nothing was updated :// this.wait = true;}}

如果桌面壁纸是可见状态下,系统服务通知有新的东西,这个类会优先把它绘制在画布上。如果没有动画了,updatePhysics会通知线程去等待。通常SurfaceView在有两个画布交替绘制的时候,会在画布上绘制上一次......

如果要让你的动态墙纸有配置功能,只要创建一个PreferenceActivity ,并将它在wallpaper.xml文件中声明。同时让SharedPreference 对象可以找到你的配置选项。

教程就写到这里,如果还有什么不懂,你可以通过Eclipse来浏览完整的源代码:SampleLiveWallpaper 。

转载:/liux/blog/40230

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。