展会信息港展会大全

Android Launcher开发之动态壁纸(LiveWallPaper)气泡流动效果
来源:互联网   发布日期:2016-01-06 19:25:14   浏览:2386次  

导读:最近在研究Laucher应用,今天写了一下四组件中的壁纸(WallPaper),关于静态壁纸的实现,比较简单,在此就不再描述. 参考了系统源代码之后,我自己做了一个简单的动态壁纸:气泡流动效果. 图案比较简单,但基本原......

最近在研究Laucher应用,今天写了一下四组件中的壁纸(WallPaper),关于静态壁纸的实现,比较简单,在此就不再描述. 参考了系统源代码之后,我自己做了一个简单的动态壁纸:气泡流动效果. 图案比较简单,但基本原理可在此例子上加以扩展,比如3D动画效果,复杂的触摸改变动画事件,有兴趣的朋友可以试一试.

大概效果如下,最开始得时候,会从四个角落的方向浮出四个气泡,然后以一定的路线移动,当移出屏幕时重新开始以新的坐标浮出,以此实现了一个简单的气泡浮动的效果:

实现的思路 :

1、新建一个Android工程 ,注意,对于Live Wallpaper来说传统的布局文件是不需要的。

2、在res下面新建一个xml文件夹 然后新建一个livewallpaper.xml 内容如下:

<?xml version="1.0" encoding="utf-8"?>

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@drawable/icon"/>

注意: 这里的android:thumbnail值得是你这个动态壁纸的小图标 会在你选着动态壁纸的时候出现,也可以不写此属性

3. 实现动态壁纸是不需要使用Activity, 创建LiveWallpaper类,让其继承WallpaperService:

实现 onCreateEngine()方法,返回自己实现的Engine类

在Engine类中的onCreate()方法中进行调用绘制图形的drawFrame()方法

定义四个圆形的起始坐标,每次调用drawFrame()时改变圆形的坐标,通过mHandler.postDelayed(drawTarget, 100);方法,进行重新绘制图形,更新UI

具体代码如下:

1.AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="org.crazyit.desktop"

android:versionCode="1"

android:versionName="1.0">

<application

android:icon="@drawable/icon"

android:label="@string/app_name">

<!-- 配置实时壁纸Service -->

<service android:label="@string/app_name"

android:name=".LiveWallpaper"

android:permission="android.permission.BIND_WALLPAPER">

<!-- 为实时壁纸配置intent-filter -->

<intent-filter>

<actionandroid:name="android.service.wallpaper.WallpaperService" />

</intent-filter>

<!-- 为实时壁纸配置meta-data -->

<meta-data android:name="android.service.wallpaper"

android:resource="@xml/livewallpaper" />

</service>

</application>

</manifest>

2. 壁纸的xml文件: livewallpaper.xml

<?xml version="1.0" encoding="utf-8"?>

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:thumbnail="@drawable/icon"/>

3. 实现动态壁纸的LiveWallpaper类:

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;

/**

*

* @author Tian

*

*/

public class LiveWallpaper extends WallpaperService

{

// 实现WallpaperService必须实现的抽象方法

public Engine onCreateEngine()

{

// 返回自定义的Engine

return new MyEngine();

}

class MyEngine extends Engine

{

// 记录程序界面是否可见

private boolean mVisible;

// 记录当前当前用户动作事件的发生位置

private float mTouchX = -1;

private float mTouchY = -1;

// 记录当前圆圈的绘制位置

//左上角坐标

private float cx1 = 15;

private float cy1 = 20;

//右下角坐标

private float cx2 = 300;

private float cy2 = 380;

//右上角坐标

private float cx3 = 300;

private float cy3 = 20;

//左下角坐标

private float cx4 = 15;

private float cy4 = 380;

// 定义画笔

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);

}

}

public void onOffsetsChanged(float xOffset, float yOffset, float xStep,

float yStep, int xPixels, int yPixels)

{

drawFrame();

}

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(cx1, cy1, 80, mPaint);

c.drawCircle(cx2, cy2, 40, mPaint);

c.drawCircle(cx3, cy3, 50, mPaint);

c.drawCircle(cx4, cy4, 60, mPaint);

c.restore();

}

}

finally

{

if (c != null)

holder.unlockCanvasAndPost(c);

}

mHandler.removeCallbacks(drawTarget);

// 调度下一次重绘

if (mVisible)

{

cx1 += 6;

cy1 += 8;

// 如果cx1、cy1移出屏幕后从左上角重新开始

if (cx1 > 320)

cx1 = 15;

if (cy1 > 400)

cy1 = 20;

cx2 -= 6;

cy2 -= 8;

// 如果cx2、cy2移出屏幕后从右下角重新开始

if (cx2 <15)

cx2 = 300;

if (cy2 <20)

cy2 = 380;

cx3 -= 6;

cy3 += 8;

// 如果cx3、cy3移出屏幕后从右上角重新开始

if (cx3 <0)

cx3 = 300;

if (cy3 >400)

cy3 = 20;

cx4 += 6;

cy4 -= 8;

// 如果cx4、cy4移出屏幕后从左下角重新开始

if (cx4 >320)

cx4 = 15;

if (cy4 <0)

cy4 = 380;

// 指定0.1秒后重新执行mDrawCube一次

mHandler.postDelayed(drawTarget, 100);

}

}

// 在屏幕触碰点绘制圆圈

private void drawTouchPoint(Canvas c)

{

if (mTouchX >= 0 && mTouchY >= 0)

{

c.drawCircle(mTouchX, mTouchY, 40, mPaint);

}

}

}

}

这样,就基本实现了一个动态壁纸:气泡浮动的效果.

不过这只是一个入门的小例子,如果想达到商用效果,还有很多方面需要进行优化:

1. 绘制更加复杂的图形

2. 使用3D Animation动画效果

3. 色彩方面需要丰富起来

4. 更新UI的方法我使用了handler的postDelay(runnable,millsecond)的方法,这里虽然实现的代码较少,但效率较低,画面仍不够流畅.

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港