2011.09.21——— android 動(dòng)態(tài)壁紙開發(fā)
參考: http://www.ophonesdn.com/article/show/278
resources/articles/live-wallpapers.html
自己做了一個(gè)非常簡(jiǎn)單的 只是想了解過程 源碼見附件 步驟如下:
1、新建一個(gè)Android工程? 然后進(jìn)入工程的/res/文件夾,刪除layout這個(gè)文件夾,當(dāng)然里面的main.xml也會(huì)被刪除的,對(duì)于Live Wallpaper來說傳統(tǒng)的布局文件是不需要的。
2、在res下面新建一個(gè)xml文件夾 然后新建一個(gè)mylivewallpaper.xml 內(nèi)容如下:
這里的android:thumbnail值得是你這個(gè)動(dòng)態(tài)壁紙的小圖標(biāo) 會(huì)在你選著動(dòng)態(tài)壁紙的時(shí)候出現(xiàn) 如下圖:
這個(gè)可以自己選一個(gè)好看一點(diǎn)的
3、開始編寫代碼了? 直接看吧
實(shí)現(xiàn)的效果是一個(gè)動(dòng)態(tài)改變的時(shí)間 如下圖:
我們一一來解釋:
onCreateEngine() :
啟動(dòng)一個(gè)WallpaperService.Engine 這個(gè)engine才是負(fù)責(zé)繪制壁紙以及響應(yīng)與用戶交互事件的核心部件 這個(gè)方法也是必須要重寫的 并且是WallpaperService和service的主要區(qū)別
onOffsetsChanged():
這個(gè)一般在幾個(gè)屏幕滑動(dòng)的時(shí)候調(diào)用 而且 當(dāng)你拖動(dòng)A屏幕向B屏幕過度時(shí) 會(huì)隨著B屏幕的顯示面積的變大或者變小一直調(diào)用這個(gè)方法
onVisibilityChanged()
這個(gè)是屏幕顯示或者不顯示的時(shí)候調(diào)用的 必須完全覆蓋屏幕才會(huì)調(diào)用
onCommand()
可以給壁紙發(fā)送一些命令 讓其執(zhí)行
onTouchEvent()
處理壁紙的點(diǎn)擊時(shí)間的
setTouchEventsEnabled(true)
作用是使壁紙能響應(yīng)touch event,默認(rèn)是false
其他的看名字應(yīng)該就知道了 呵呵
這里也說下Engine的慣用寫法吧
4、在AndroidManifes.xml里面注冊(cè)service
除了
5、自己的一些關(guān)于方法執(zhí)行順序的測(cè)試信息:
當(dāng)進(jìn)入改壁紙的設(shè)置頁(yè)面 但是還沒有設(shè)置時(shí)
09-21 07:55:05.575: INFO/System.out(1337): service onCreate
09-21 07:55:05.614: INFO/System.out(1337): service onCreateEngine
09-21 07:55:05.634: INFO/System.out(1337): MyEngine
09-21 07:55:05.663: INFO/System.out(1337): onCreate
09-21 07:55:05.746: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:05.753: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:05.785: INFO/System.out(1337): onVisibilityChanged
當(dāng)點(diǎn)擊設(shè)置壁紙按鈕后
09-21 07:55:19.434: INFO/System.out(1337): onTouchEvent
09-21 07:55:19.574: INFO/System.out(1337): onTouchEvent
09-21 07:55:20.283: INFO/System.out(1337): service onCreateEngine
09-21 07:55:20.294: INFO/System.out(1337): MyEngine
09-21 07:55:20.304: INFO/System.out(1337): onCreate
09-21 07:55:20.414: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:20.424: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:20.443: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:20.443: INFO/System.out(1337): onoffsetsChanged
09-21 07:55:20.863: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:21.305: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:55:21.333: INFO/System.out(1337): onDestroy
在壁紙上面點(diǎn)擊
09-21 07:55:34.654: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onCommand
啟動(dòng)其他程序 完全覆蓋屏幕
09-21 07:56:03.855: INFO/System.out(1337): onTouchEvent
09-21 07:56:03.884: INFO/System.out(1337): onTouchEvent
09-21 07:56:04.494: INFO/System.out(1337): onVisibilityChanged
設(shè)置其他壁紙 代替自己的壁紙
09-21 07:56:34.893: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:56:34.893: INFO/System.out(1337): onDestroy
09-21 07:56:34.953: INFO/System.out(1337): service onDestory
另:Engine的生命周期:
參考: http://www.ophonesdn.com/article/show/278
resources/articles/live-wallpapers.html
自己做了一個(gè)非常簡(jiǎn)單的 只是想了解過程 源碼見附件 步驟如下:
1、新建一個(gè)Android工程? 然后進(jìn)入工程的/res/文件夾,刪除layout這個(gè)文件夾,當(dāng)然里面的main.xml也會(huì)被刪除的,對(duì)于Live Wallpaper來說傳統(tǒng)的布局文件是不需要的。
2、在res下面新建一個(gè)xml文件夾 然后新建一個(gè)mylivewallpaper.xml 內(nèi)容如下:
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:thumbnail="@drawable/icon"
/>
這里的android:thumbnail值得是你這個(gè)動(dòng)態(tài)壁紙的小圖標(biāo) 會(huì)在你選著動(dòng)態(tài)壁紙的時(shí)候出現(xiàn) 如下圖:
這個(gè)可以自己選一個(gè)好看一點(diǎn)的
3、開始編寫代碼了? 直接看吧
package com.lp.wallpaper;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class MyWallpaper extends WallpaperService{
private Handler handler = new Handler();
@Override
public void onCreate() {
System.out.println("service onCreate");
super.onCreate();
}
@Override
public void onDestroy() {
System.out.println("service onDestory");
super.onDestroy();
}
@Override
public Engine onCreateEngine() {
System.out.println("service onCreateEngine");
return new MyEngine();
}
private class MyEngine extends Engine{
private float x = 200;
private float y = 300;
private Paint mPaint;
private boolean mVisible = false;
private Runnable drawThread = new Runnable() {
public void run() {
drawWallpaper();
}
};
public MyEngine(){
System.out.println("MyEngine");
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(24);
}
@Override
public Bundle onCommand(String action, int x, int y, int z, Bundle extras, boolean resultRequested) {
// TODO Auto-generated method stub
System.out.println("onCommand");
return super.onCommand(action, x, y, z, extras, resultRequested);
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
System.out.println("onCreate");
super.onCreate(surfaceHolder);
//作用是使壁紙能響應(yīng)touch event,默認(rèn)是false
setTouchEventsEnabled(true);
}
@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
handler.removeCallbacks(drawThread);
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
// TODO Auto-generated method stub
System.out.println("onoffsetsChanged");
super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset);
}
@Override
public void onVisibilityChanged(boolean visible) {
System.out.println("onVisibilityChanged");
mVisible = visible;
if (visible) {
//開始
handler.postDelayed(drawThread, 50);
} else {
handler.removeCallbacks(drawThread);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("onSurfaceChanged");
// TODO Auto-generated method stub
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
System.out.println("onSurfaceCreated");
super.onSurfaceCreated(holder);
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
System.out.println("onSurfaceDestoryed");
// TODO Auto-generated method stub
super.onSurfaceDestroyed(holder);
handler.removeCallbacks(drawThread);
}
@Override
public void onTouchEvent(MotionEvent event) {
System.out.println("onTouchEvent");
// TODO Auto-generated method stub
super.onTouchEvent(event);
}
private void drawWallpaper() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = holder.lockCanvas();
drawTime(canvas);
holder.unlockCanvasAndPost(canvas);
//循環(huán)執(zhí)行
handler.postDelayed(drawThread, 50);
}
private void drawTime(Canvas canvas) {
Date date = new Date(System.currentTimeMillis());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String dataStr = sdf.format(date);
canvas.save();
canvas.drawColor(0xff00ff00);
canvas.drawText(dataStr, x, y, mPaint);
canvas.restore();
}
}
}
實(shí)現(xiàn)的效果是一個(gè)動(dòng)態(tài)改變的時(shí)間 如下圖:
我們一一來解釋:
onCreateEngine() :
啟動(dòng)一個(gè)WallpaperService.Engine 這個(gè)engine才是負(fù)責(zé)繪制壁紙以及響應(yīng)與用戶交互事件的核心部件 這個(gè)方法也是必須要重寫的 并且是WallpaperService和service的主要區(qū)別
onOffsetsChanged():
這個(gè)一般在幾個(gè)屏幕滑動(dòng)的時(shí)候調(diào)用 而且 當(dāng)你拖動(dòng)A屏幕向B屏幕過度時(shí) 會(huì)隨著B屏幕的顯示面積的變大或者變小一直調(diào)用這個(gè)方法
onVisibilityChanged()
這個(gè)是屏幕顯示或者不顯示的時(shí)候調(diào)用的 必須完全覆蓋屏幕才會(huì)調(diào)用
onCommand()
可以給壁紙發(fā)送一些命令 讓其執(zhí)行
onTouchEvent()
處理壁紙的點(diǎn)擊時(shí)間的
setTouchEventsEnabled(true)
作用是使壁紙能響應(yīng)touch event,默認(rèn)是false
其他的看名字應(yīng)該就知道了 呵呵
這里也說下Engine的慣用寫法吧
private class MyEngine extends Engine{
//這里定義一個(gè)線程
private Runnable drawThread = new Runnable() {
public void run() {
drawWallpaper();
}
};
//構(gòu)造方法里面 一般初始化Paint對(duì)象
public MyEngine(){
System.out.println("MyEngine");
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(4);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setTextSize(24);
}
//這里 調(diào)用setTouchEventsEnabled(true);即可
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
System.out.println("onCreate");
super.onCreate(surfaceHolder);
//作用是使壁紙能響應(yīng)touch event,默認(rèn)是false
setTouchEventsEnabled(true);
}
//取消callback
@Override
public void onDestroy() {
System.out.println("onDestroy");
super.onDestroy();
handler.removeCallbacks(drawThread);
}
//當(dāng)顯示的時(shí)候 綁定callback 不顯示時(shí) 取消callback
@Override
public void onVisibilityChanged(boolean visible) {
System.out.println("onVisibilityChanged");
mVisible = visible;
if (visible) {
//開始
handler.postDelayed(drawThread, 50);
} else {
handler.removeCallbacks(drawThread);
}
}
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
System.out.println("onSurfaceChanged");
// TODO Auto-generated method stub
super.onSurfaceChanged(holder, format, width, height);
}
@Override
public void onSurfaceCreated(SurfaceHolder holder) {
System.out.println("onSurfaceCreated");
super.onSurfaceCreated(holder);
}
//取消callback
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
System.out.println("onSurfaceDestoryed");
// TODO Auto-generated method stub
super.onSurfaceDestroyed(holder);
handler.removeCallbacks(drawThread);
}
//處理點(diǎn)擊事件 比如說 點(diǎn)擊時(shí) 出現(xiàn)水波等
@Override
public void onTouchEvent(MotionEvent event) {
System.out.println("onTouchEvent");
// TODO Auto-generated method stub
super.onTouchEvent(event);
}
//得到surfaceholder和canvas 并調(diào)用核心處理方法
private void drawWallpaper() {
SurfaceHolder holder = getSurfaceHolder();
Canvas canvas = holder.lockCanvas();
drawTime(canvas);
holder.unlockCanvasAndPost(canvas);
//循環(huán)執(zhí)行
handler.postDelayed(drawThread, 50);
}
//核心處理方法
private void drawTime(Canvas canvas) {
}
}
4、在AndroidManifes.xml里面注冊(cè)service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lp.wallpaper">
<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<service
android:label="@string/app_name"
android:name=".MyWallpaper"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<meta-data android:name="android.service.wallpaper" android:resource="@xml/mylivewallpaper" />
</service>
</application>
</manifest>
除了
android:resource="@xml/mylivewallpaper"
是可以自己修改 其他的都是必須得 特別強(qiáng)調(diào)幾個(gè):
<uses-sdk android:minSdkVersion="7" />
<uses-feature android:name="android.software.live_wallpaper" />
android:permission="android.permission.BIND_WALLPAPER"
5、自己的一些關(guān)于方法執(zhí)行順序的測(cè)試信息:
當(dāng)進(jìn)入改壁紙的設(shè)置頁(yè)面 但是還沒有設(shè)置時(shí)
09-21 07:55:05.575: INFO/System.out(1337): service onCreate
09-21 07:55:05.614: INFO/System.out(1337): service onCreateEngine
09-21 07:55:05.634: INFO/System.out(1337): MyEngine
09-21 07:55:05.663: INFO/System.out(1337): onCreate
09-21 07:55:05.746: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:05.753: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:05.785: INFO/System.out(1337): onVisibilityChanged
當(dāng)點(diǎn)擊設(shè)置壁紙按鈕后
09-21 07:55:19.434: INFO/System.out(1337): onTouchEvent
09-21 07:55:19.574: INFO/System.out(1337): onTouchEvent
09-21 07:55:20.283: INFO/System.out(1337): service onCreateEngine
09-21 07:55:20.294: INFO/System.out(1337): MyEngine
09-21 07:55:20.304: INFO/System.out(1337): onCreate
09-21 07:55:20.414: INFO/System.out(1337): onSurfaceCreated
09-21 07:55:20.424: INFO/System.out(1337): onSurfaceChanged
09-21 07:55:20.443: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:20.443: INFO/System.out(1337): onoffsetsChanged
09-21 07:55:20.863: INFO/System.out(1337): onVisibilityChanged
09-21 07:55:21.305: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:55:21.333: INFO/System.out(1337): onDestroy
在壁紙上面點(diǎn)擊
09-21 07:55:34.654: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onTouchEvent
09-21 07:55:34.754: INFO/System.out(1337): onCommand
啟動(dòng)其他程序 完全覆蓋屏幕
09-21 07:56:03.855: INFO/System.out(1337): onTouchEvent
09-21 07:56:03.884: INFO/System.out(1337): onTouchEvent
09-21 07:56:04.494: INFO/System.out(1337): onVisibilityChanged
設(shè)置其他壁紙 代替自己的壁紙
09-21 07:56:34.893: INFO/System.out(1337): onSurfaceDestoryed
09-21 07:56:34.893: INFO/System.out(1337): onDestroy
09-21 07:56:34.953: INFO/System.out(1337): service onDestory
另:Engine的生命周期:
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫作最大的動(dòng)力,如果您喜歡我的文章,感覺我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

