随时随地阅读更多技术实战干货,获取项目源码、学习资料,请关注源代码社区公众号(ydmsq666)
所谓实时壁纸,即动态壁纸,就是手机桌面不再是简单的图片,而是运行中的动画,该动画由程序实时绘制的,所以称为实时壁纸。Android中提供WallpaperService基类来开发实时壁纸,步骤如下:
下面用一个示例来演示,该示例原型来源于疯狂讲义一书,代码如下:
WallpaperService的子类:LiveWallpaper
package com.home.service;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class LiveWallpaper extends WallpaperService {
// 继承WallpaperService必须实现的抽象方法
@Override
public Engine onCreateEngine() {
// 返回自定义的Engine
return new MyEngine();
}
class MyEngine extends Engine {
private int ScreenWidth;
private int ScreenHeight;
// 记录程序界面是否可见
private boolean mVisible;
// 记录当前用户事件的发生位置
private float mTouchX = -1;
private float mTouchY = -1;
// 记录当前圆圈的绘制位置
private float cx = 15;
private float cy = 15;
// 定义画笔
private Paint mPaint = new Paint();
// 定义一个Handler
Handler mHandler = new Handler();
// 定义一个周期性执行的任务
private final Runnable drawTarget = new Runnable() {
@Override
public void run() {
drawFrame();
}
};
public void onCreate(android.view.SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
// 获得屏幕宽和高
ScreenWidth = getDesiredMinimumWidth() / 2;
ScreenHeight = getDesiredMinimumHeight();
// 初始化画笔
mPaint.setColor(0xffffffff);
mPaint.setAntiAlias(true);
mPaint.setStrokeWidth(2);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStyle(Paint.Style.STROKE);
// 设置处理触摸事件
setTouchEventsEnabled(true);
}
@Override
public void onDestroy() {
super.onDestroy();
// 删除回调
mHandler.removeCallbacks(drawTarget);
}
@Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
// 当界面可见时,执行drawFrame()方法
if (mVisible) {
// 动态绘制图形
drawFrame();
} else {
// 如果界面不可见,删除回调
mHandler.removeCallbacks(drawTarget);
}
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset,
float xOffsetStep, float yOffsetStep, int xPixelOffset,
int yPixelOffset) {
drawFrame();
}
// 当屏幕大小改变时调用该方法
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
drawFrame();
}
@Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(drawTarget);
}
@Override
public void onTouchEvent(MotionEvent event) {
// 如果检测到滑动操作
if (event.getAction() == MotionEvent.ACTION_MOVE) {
mTouchX = event.getX();
mTouchY = event.getY();
} else {
mTouchX = -1;
mTouchY = -1;
}
super.onTouchEvent(event);
}
/**
* 定义绘制图形的工具方法
*/
private void drawFrame() {
// 获取该壁纸的SurfaceHolder对象
final SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
// 对画布加锁
c = holder.lockCanvas();
if (c != null) {
c.save();
// 绘制背景色
c.drawColor(0xff000000);
// 在触碰点绘制圆圈
drawTouchPoint(c);
// 绘制圆圈
c.drawCircle(cx, cy, 80, mPaint);
c.restore();
}
} finally {
if (c != null) {
holder.unlockCanvasAndPost(c);
}
}
mHandler.removeCallbacks(drawTarget);
// 调度下一次重绘
if (mVisible) {
cx += 15;
cy += 20;
// 如果cx、cy移出屏幕,从左上角重新开始
if (cx >= ScreenWidth - 80) {
cx = 15;
}
if (cy >= ScreenHeight - 80) {
cy = 20;
}
// 指定0.1秒后重新执行一次drawTarget
mHandler.postDelayed(drawTarget, 100);
}
}
/**
* 在屏幕触碰点绘制圆圈
*
* @param canvas
*/
private void drawTouchPoint(Canvas canvas) {
if (mTouchX >= 0 && mTouchY >= 0) {
canvas.drawCircle(mTouchX, mTouchY, 40, mPaint);
}
}
}
}
配置LiveWallpaper:
<service
android:name="com.home.service.LiveWallpaper"
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/mywallpaperxml"/>
</service>
mywallpaperxml:
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/wallpaper_des"
android:thumbnail="@drawable/ic_launcher">
</wallpaper>
权限:
<!-- 加入设置壁纸权限 -->
<uses-permission android:name="android.permission.SET_WALLPAPER" />