2024年1月7日发(作者:)
动态壁纸是在Android 2.1新增的一个功能。动态壁纸可以添加到Android的桌面,具有交互式的动画背景效果。在本教程中,我们将教会你如何去制作一个交互式的动态壁纸。
动态壁纸是一个Android应用程序,包括一个服务(WallpaperService)。该服务必须包括一个引擎()。该引擎是连接用户、桌面、系统之间的桥梁。它也可以绘制桌面壁纸。
首先,必须由内在的Engine类创建一个WallpaperService类。该服务必须在中声明为"perService",这样它才会作为动态壁纸被手机识别。而且还要在服务配置中附加"_WALLPAPER"的权限许可:
1
2 android:name="LiveWallpaperService" 3 android:enabled="true" 4 android:icon="@drawable/icon" 5 android:label="@string/app_name" 6 android:permission="_WALLPAPER"> 7 8 9 android:name="perService" /> 10 11 12 android:name="per" 13 android:resource="@xml/wallpaper" />
创建一个XML文件,放置在应用程序目录下的/res/xml/中。它用来描述你的动态壁纸。
1
2
3 xmlns:android="/apk/res/android" 4 android:thumbnail="@drawable/thumbnail" 5 android:description="@string/description" 6 android:settingsActivity="PreferenceActivity"/> 再创建一个xml的属性文件 ,代码如下: 1 2 4 5 6 7 8 9 10 11 12 13 14 动态壁纸的服务代码如下: 1 package llpaper; 2 3 import Preferences; 4 import perService; 5 import Event; 6 import eHolder; 7 8 /** 9 * Android Live Wallpaper Archetype 10 * 11 rel="nofollow">@author 12 * under GPL v3 : /licenses/ 13 */ 14 public class LiveWallpaperService extends WallpaperService { 15 16 @Override 17 public Engine onCreateEngine() { 18 return new SampleEngine(); 19 } 20 21 @Override 22 public void onCreate() { 23 te(); 24 } 25 26 @Override 27 public void onDestroy() { 28 roy(); 29 } 30 31 public class SampleEngine extends Engine { 32 33 private LiveWallpaperPainting painting; 34 35 SampleEngine() { 36 SurfaceHolder holder = getSurfaceHolder(); 37 painting = new LiveWallpaperPainting(holder, 38 getApplicationContext()); 39 } 40 41 @Override 42 public void onCreate(SurfaceHolder surfaceHolder) { 43 te(surfaceHolder); 44 // register listeners and callbacks here 45 setTouchEventsEnabled(true); 46 } 47 48 @Override 49 public void onDestroy() { 50 roy(); 51 // remove listeners and callbacks here 52 inting(); 53 } 54 55 @Override 56 public void onVisibilityChanged(boolean visible) { 57 if (visible) { 58 // register listeners and callbacks here 59 Painting(); 60 } else { 61 // remove listeners and callbacks here 62 ainting(); 63 } 64 } 65 66 @Override 67 public void onSurfaceChanged(SurfaceHolder holder, int format, 68 int width, int height) { 69 aceChanged(holder, format, width, height); 70 faceSize(width, height); 71 } 72 73 @Override 74 public void onSurfaceCreated(SurfaceHolder holder) { 75 aceCreated(holder); 76 // start painting 77 (); 78 } 79 80 @Override 81 public void onSurfaceDestroyed(SurfaceHolder holder) { 82 aceDestroyed(holder); 83 boolean retry = true; 84 inting(); 85 while (retry) { 86 try { 87 (); 88 retry = false; 89 } catch (InterruptedException e) {} 90 } 91 } 92 93 @Override 94 public void onOffsetsChanged(float xOffset, float yOffset, 95 float xStep, float yStep, int xPixels, int yPixels) { 96 } 97 98 @Override 99 public void onTouchEvent(MotionEvent event) { 100 hEvent(event); 101 hEvent(event); 102 } 103 104 } 105 } 当壁纸的显示、状态或大小变化是,会调用Engine的onCreate, onDestroy, onVisibilityChanged,onSurfaceChanged, onSurfaceCreated 和 onSurfaceDestroyed方法。有了这些方法,动态壁纸才能展现出动画效果。而通 过设置setTouchEventsEnabled(true),并且调用onTouchEvent(MotionEvent event)方法,来激活触摸事件。 我们在绘画墙纸的时候,也会使用一个单独的绘画线程: 1 package llpaper; 2 3 import t; 4 import ; 5 import Event; 6 import eHolder; 7 8 /** 9 * Android Live Wallpaper painting thread Archetype 10 * 11 rel="nofollow">@author 12 * GPL v3 : /licenses/ 13 */ 14 public class LiveWallpaperPainting extends Thread { 15 16 /** Reference to the View and the context */ 17 private SurfaceHolder surfaceHolder; 18 private Context context; 19 20 /** State */ 21 private boolean wait; 22 private boolean run; 23 24 /** Dimensions */ 25 private int width; 26 private int height; 27 28 /** Time tracking */ 29 private long previousTime; 30 private long currentTime; 31 32 public LiveWallpaperPainting(SurfaceHolder surfaceHolder, 33 Context context) { 34 // keep a reference of the context and the surface 35 // the context is needed if you want to inflate 36 // some resources from your livewallpaper .apk 37 eHolder = surfaceHolder; 38 t = context; 39 // don't animate until surface is created and displayed 40 = true; 41 } 42 43 /** 44 * Pauses the live wallpaper animation 45 */ 46 public void pausePainting() { 47 = true; 48 synchronized(this) { 49 (); 50 } 51 } 52 53 /** 54 * Resume the live wallpaper animation 55 */ 56 public void resumePainting() { 57 = false; 58 synchronized(this) { 59 (); 60 } 61 } 62 63 /** 64 * Stop the live wallpaper animation 65 */ 66 public void stopPainting() { 67 = false; 68 synchronized(this) { 69 (); 70 } 71 } 72 73 @Override 74 public void run() { 75 = true; 76 Canvas c = null; 77 while (run) { 78 try { 79 c = nvas(null); 80 synchronized (eHolder) { 81 currentTime = tTimeMillis(); 82 updatePhysics(); 83 doDraw(c); 84 previousTime = currentTime; 85 } 86 } finally { 87 if (c != null) { 88 CanvasAndPost(c); 89 } 90 } 91 // pause if no need to animate 92 synchronized (this) { 93 if (wait) { 94 try { 95 wait(); 96 } catch (Exception e) {} 97 } 98 } 99 } 100 } 101 102 /** 103 * Invoke when the surface dimension change 104 */ 105 public void setSurfaceSize(int width, int height) { 106 = width; 107 = height; 108 synchronized(this) { 109 (); 110 } 111 } 112 113 /** 114 * Invoke while the screen is touched 115 */ 116 public void doTouchEvent(MotionEvent event) { 117 // handle the event here 118 // if there is something to animate 119 // then wake up 120 = false; 121 synchronized(this) { 122 notify(); 123 } 124 } 125 126 /** 127 * Do the actual drawing stuff 128 */ 129 private void doDraw(Canvas canvas) {} 130 131 /** 132 * Update the animation, sprites or whatever. 133 * If there is nothing to animate set the wait 134 * attribute of the thread to true 135 */ 136 private void updatePhysics() { 137 // if nothing was updated : 138 // = true; 139 } 140 } 如果桌面壁纸是可见状态下,系统服务通知有新的东西,这个类会优先把它绘制在画布上。如果没有动画了,updatePhysics会通知线程去等待。通常SurfaceView在有两个画布交替绘制的时候,会在画布上绘制上一次......


发布评论