package org.crazyit.desktop;
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;
/**
为了开发动态壁纸,android使用了WallpaperService,子类必须实现它的onCreateEngine()方法
该服务必须包括一个引擎(WallpaperService.Engine)。该引擎是连接用户、桌面、系统之间的桥梁。
它也可以绘制桌面壁纸,并采用了与surfaceview相同的绘图机制。所以,需实现WallpaperService.Engine的子类,并重写onVisibilityChanged
onOffsetsChanged等方法。
*/
public class LiveWallpaper extends WallpaperService
{
// 实现WallpaperService必须实现的抽象方法
@Override
public Engine onCreateEngine()
{
// 返回自定义的Engine
return new MyEngine();
}
class MyEngine extends Engine
{
// 记录程序界面是否可见
private boolean mVisible;
// 记录当前当前用户动作事件的发生位置
private float mTouchX = -1;
private float mTouchY = -1;
// 记录当前圆圈的绘制位置
private float cx = 15;
private float cy = 20;
// 定义画笔
private Paint mPaint = new Paint();
// 定义一个Handler
Handler mHandler = new Handler();
// 定义一个周期性执行的任务
private final Runnable drawTarget = new Runnable()
{
public void run()
{
drawFrame();
}
};
@Override
public void onCreate(SurfaceHolder surfaceHolder)
{
super.onCreate(surfaceHolder);
// 初始化画笔
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 (visible)
{
// 动态地绘制图形
drawFrame();
}
else
{
// 如果界面不可见,删除回调
mHandler.removeCallbacks(drawTarget);
}
}
@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
float yStep, int xPixels, int yPixels)
{
drawFrame();
}
WallpaperService.Engine采用了与surfaceview相同的绘图机制,因此可以有选择性的重写下面3个方法
// // 当屏幕大小改变时候调用该方法
// @Override
// public void onSurfaceChanged(SurfaceHolder holder, int format,
// int width, int height)
// {
// super.onSurfaceChanged(holder, format, width, height);
// drawFrame();
// }
//
// @Override
// public void onSurfaceCreated(SurfaceHolder holder)
// {
// super.onSurfaceCreated(holder);
// }
//
// @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 > 320)
cx = 15;
if (cy > 400)
cy = 20;
// 指定0.1秒后重新执行mDrawCube一次
mHandler.postDelayed(drawTarget, 100);
}
}
// 在屏幕触碰点绘制圆圈
private void drawTouchPoint(Canvas c)
{
if (mTouchX >= 0 && mTouchY >= 0)
{
c.drawCircle(mTouchX, mTouchY, 40, mPaint);
}
}
}
}
<!-- 配置实时壁纸Service -->
<service android:label="@string/app_name"
android:name=".LiveWallpaper"
android:permission="android.permission.BIND_WALLPAPER">
<!-- 为实时壁纸配置intent-filter -->
<intent-filter>
<action android:name="android.service.wallpaper.WallpaperService" />
</intent-filter>
<!-- 为实时壁纸配置meta-data -->
<meta-data android:name="android.service.wallpaper"
android:resource="@xml/livewallpaper" />
</service>
<?xml version="1.0" encoding="utf-8"?>
<wallpaper xmlns:android="http://schemas.android.com/apk/res/android"/>
动态壁纸的原理和surfaceview原理差不多。
/**
快捷方式添加
*/
public class AddShortcut extends Activity
{
ImageView flower;
// 定义两份动画资源
Animation anim, reverse;
final Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
if (msg.what == 0x123)
{
flower.startAnimation(reverse);
}
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
flower = (ImageView) findViewById(R.id.flower);
// 加载第一份动画资源
//补间动画 Teen Animation
Android中实现补间动画的思路是这样的,
1、首先用XML定义一个动画效果
2、依据这个XML使用AnimationUtils工具类创建一个Animationd对象
3、调用View组件的startAnimation方法实现动画。使用动画的对象是一个view,这里是imageview
anim = AnimationUtils.loadAnimation(this, R.anim.anim);
// 设置动画结束后保留结束状态
anim.setFillAfter(true);
// 加载第二份动画资源
reverse = AnimationUtils.loadAnimation(this, R.anim.reverse);
// 设置动画结束后保留结束状态
reverse.setFillAfter(true);
Button bn = (Button) findViewById(R.id.bn);
// 下面的代码是点击了按钮即为本应用创建一个shortcut 快捷方式
bn.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
// 创建添加快捷方式的Intent
Intent addIntent = new Intent(
"com.android.launcher.action.INSTALL_SHORTCUT");
String title = getResources().getString(R.string.title);
// 加载快捷方式的图标
Parcelable icon = Intent.ShortcutIconResource.fromContext(
AddShortcut.this, R.drawable.icon);
// 创建点击快捷方式后操作Intent,该处当点击创建的快捷方式后,再次启动该程序
Intent myIntent = new Intent(AddShortcut.this,
AddShortcut.class);
// 设置快捷方式的标题
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
// 设置快捷方式的图标
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
// 设置快捷方式对应的Intent
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, myIntent);
// 发送广播添加快捷方式
sendBroadcast(addIntent);
}
});
}
@Override
public void onResume()
{
super.onResume();
// 开始执行动画
flower.startAnimation(anim);
// 设置3.5秒后启动第二个动画
new Timer().schedule(new TimerTask()
{
@Override
public void run()
{
handler.sendEmptyMessage(0x123);
}
}, 3500);
}
}