android 动态壁纸

引用:http://www.ophonesdn.com/article/show/278

http://developer.android.com/resources/samples/CubeLiveWallpaper/src/com/example/android/livecubes/cube1/CubeWallpaper1.html

标签 : 动态壁纸 Live Wallpapers 时间壁纸 TimeWall

 

随着三星Oscar的上市,流畅的操作,华丽的界面,OPhone 2.0的不俗表现不禁让人眼前一亮。作为OPhone 2.0一个新特性,动态壁纸(Live Wallpapers)为用户带来了更炫体验。本文主要通过一个完整的时间壁纸(TimeWall)为大家介绍如何开发 Live Wallpapers。还没开发环境?赶紧去下载OPhone SDK 2.0吧!

1、 Live Wallpapers是什么?
在oscar上有一个动态壁纸叫“天空草地”,用过一段时间,可以发现,随着时间的变化,壁纸的天空就会由蓝蓝青天变成繁星满天。看看效果:
为什么壁纸还有这么神奇的变化,这中间到底是什么在起作用?其实,一个Live Wallpaper就是一个apk!也就是说,动态壁纸的实质是一个apk在后台不断地重绘壁纸,所以我们可以让小草长高,小鸟飞翔。
来看一下我们TimeWall的AndoridManifest.xml:
view plaincopy to clipboardprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     package="com.oms.LiveWall" android:versionCode="1"  
  4.     android:versionName="1.0">  
  5.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  6.         <service android:label="@string/app_name" android:name=".TimeWall"  
  7.             android:permission="android.permission.BIND_WALLPAPER">  
  8.             <intent-filter>  
  9.                 <action android:name="android.service.wallpaper.WallpaperService" />  
  10.             </intent-filter>  
  11.             <meta-data android:name="android.service.wallpaper"  
  12.                 android:resource="@xml/alive_wall" />  
  13.         </service>  
  14.     </application>  
  15.     <uses-sdk android:minSdkVersion="7" />  
  16. </manifest>  
原来如此简单,动态壁纸仅仅有一个service就够了。其中
android:permission="android.permission.BIND_WALLPAPER"
是让该service有能设置为壁纸的权限,没有的话该壁纸只能被预览。
<uses-sdk android:minSdkVersion="7" />
告诉我们,如果你想开发一个live wallpaper,必须是OPhone 2.0或者更高的版本。当然这也需要手机硬件的支持。
2、怎样实现WallpaperService?
WallpaperService与其他的service唯一的不同就是,你必须要增加一个方法onCreateEngine(),它会返回一个WallpaperService.Engine,这个engine才是负责绘制壁纸以及响应与用户交互事件的核心部件。这个service代码结构如下:
view plaincopy to clipboardprint?
  1. public class TimeWall extends WallpaperService {  
  2.    
  3.     public Engine onCreateEngine() {  
  4.         return new TimeEngine();  
  5.     }  
  6.    
  7.     public class TimeEngine extends Engine {  
  8.         // ...more code  
  9.     }  
  10. }  
类TimeEngine才是处理壁纸的核心类,我们会在类TimeEngine中加上自己的逻辑以完成壁纸的绘制、变化以及销毁。Engine的生命周期与大多数OPhone应用程序组件,比如activity类似,都是从onCreate()开始,在销毁时调用onDestory()方法。不同的是WallpaperService会提供一个surface用来绘制壁纸,所以在生命周期中多一个onSurfaceCreated与onSurfaceDestroyed的过程。下面是一个最简生命周期:
也就是说只要我们实现上面四个方法,一个基本的LiveWallpaper就可以完成了。让我们逐个看一下这几个方法的实现。
view plaincopy to clipboardprint?
  1. @Override  
  2. public void onCreate(SurfaceHolder surfaceHolder) {  
  3.     super.onCreate(surfaceHolder);  
  4.     setTouchEventsEnabled(true);  
  5. }  
  6.   
  7. @Override  
  8. public void onDestroy() {  
  9.     super.onDestroy();  
  10.     mHandler.removeMessages(DRAW);  
  11. }  
  12.   
  13. @Override  
  14. public void onSurfaceCreated(SurfaceHolder holder) {  
  15.     super.onSurfaceCreated(holder);  
  16.     mHandler.sendEmptyMessage(DRAW);  
  17. }  
  18.   
  19. @Override  
  20. public void onSurfaceDestroyed(SurfaceHolder holder) {  
  21.     super.onSurfaceDestroyed(holder);  
  22.     mHandler.removeMessages(DRAW);  
  23. }  
在onCreate方法里,我们
setTouchEventsEnabled(true);
作用是使壁纸能响应touch event,默认是false。TimeWall会在用户点击屏幕的时候画一个十字架,所以我们需要设置其为true。
可以看到我们在这四个方法里面做的事情非常简单,就是在create时候发一个message,执行画面的绘制,在destory时remove这个消息。看一下mHandler的代码:
view plaincopy to clipboardprint?
  1. private Handler mHandler = new Handler() {  
  2.       public void handleMessage(Message msg) {  
  3.           switch (msg.what) {  
  4.           case DRAW:  
  5.               drawWall();  
  6.               break;  
  7.           }  
  8.       }  
  9.   };  
方法drawWall():
view plaincopy to clipboardprint?
  1. private void drawWall() {  
  2.             SurfaceHolder holder = getSurfaceHolder();  
  3.             Canvas canvas = holder.lockCanvas();  
  4.             drawTime(canvas);  
  5.             drawCross(canvas);  
  6.             holder.unlockCanvasAndPost(canvas);  
  7.    
  8.             mHandler.removeMessages(DRAW);  
  9.             mHandler.sendEmptyMessageDelayed(DRAW, 50);  
  10.         }  
从上面可以看出,动态壁纸实际上就是不断刷新的静态壁纸,越华丽越流畅,CPU就消耗越大,对于现在的本来电量就不怎么地的智能机来说,耗电也是很可观的。但是偶尔向朋友们炫一下还是绝对可行的。drawTime()与drawCross()的内容可以由家自己实现,在TimeWall里,它们比较简单。drawTime()是计算下一处Time String应该移动到的坐标,以及画出这个String。drawCross()的作用是在用户触发onTouchEvent时画一个十字架。因为TimeWall比较简单,如果大家自己实现的画图比较复杂,可以另外开启一个线程来刷新UI,否则有可能主线程被阻塞掉。(代码见附件)
看看TimeWall的效果:

附件代码:
 
 

view plaincopy to clipboardprint?
  1. package com.OPhonesdn.timewall;  
  2.    
  3. import java.text.SimpleDateFormat;  
  4. import java.util.Date;  
  5.    
  6. import android.graphics.Canvas;  
  7. import android.graphics.Color;  
  8. import android.graphics.Paint;  
  9. import android.os.Handler;  
  10. import android.os.Message;  
  11. import android.service.wallpaper.WallpaperService;  
  12. import android.view.MotionEvent;  
  13. import android.view.SurfaceHolder;  
  14.    
  15. public class TimeWall extends WallpaperService {  
  16.    
  17.     public Engine onCreateEngine() {  
  18.         return new TimeEngine();  
  19.     }  
  20.    
  21.     public class TimeEngine extends Engine {  
  22.    
  23.         private final float STEP_X = 2f;  
  24.         private final float STEP_Y = 7f;  
  25.         private final float SCOPE_LEFT = 10f;  
  26.         private final float SCOPE_RIGHT = 110f;  
  27.         private final float SCOPE_TOP = 250f;  
  28.         private final float SCOPE_BOTTOM = 600f;  
  29.         private final float RADIUS = 20f;  
  30.         private final int DIRECTION_1 = 1// move to right top side  
  31.         private final int DIRECTION_2 = 2// move to right bottom side  
  32.         private final int DIRECTION_3 = 3// move to left bottom side  
  33.         private final int DIRECTION_4 = 4// move to left top side  
  34.         private final int DRAW = 1;  
  35.         private float mTouchX = -1f;  
  36.         private float mTouchY = -1f;  
  37.         private float mLocationX = 0f;  
  38.         private float mLocationY = 400f;  
  39.         private int mDirection = 1;  
  40.    
  41.         private Paint mPaint = new Paint();  
  42.         private Handler mHandler = new Handler() {  
  43.             public void handleMessage(Message msg) {  
  44.                 switch (msg.what) {  
  45.                 case DRAW:  
  46.                     drawWall();  
  47.                     break;  
  48.                 }  
  49.             }  
  50.         };  
  51.    
  52.         public TimeEngine() {  
  53.             mPaint.setColor(Color.RED);  
  54.             mPaint.setAntiAlias(true);  
  55.             mPaint.setStrokeWidth(4);  
  56.             mPaint.setStrokeCap(Paint.Cap.BUTT);  
  57.             mPaint.setStyle(Paint.Style.STROKE);  
  58.             mPaint.setTextSize(40);  
  59.         }  
  60.    
  61.         @Override  
  62.         public void onCreate(SurfaceHolder surfaceHolder) {  
  63.             super.onCreate(surfaceHolder);  
  64.             setTouchEventsEnabled(true);  
  65.         }  
  66.    
  67.         @Override  
  68.         public void onDestroy() {  
  69.             super.onDestroy();  
  70.             mHandler.removeMessages(DRAW);  
  71.         }  
  72.    
  73.         @Override  
  74.         public void onSurfaceCreated(SurfaceHolder holder) {  
  75.             super.onSurfaceCreated(holder);  
  76.             mHandler.sendEmptyMessage(DRAW);  
  77.         }  
  78.    
  79.         @Override  
  80.         public void onSurfaceDestroyed(SurfaceHolder holder) {  
  81.             super.onSurfaceDestroyed(holder);  
  82.             mHandler.removeMessages(DRAW);  
  83.         }  
  84.    
  85.         @Override  
  86.         public void onTouchEvent(MotionEvent event) {  
  87.             if (event.getAction() == MotionEvent.ACTION_MOVE  
  88.                     || event.getAction() == MotionEvent.ACTION_DOWN) {  
  89.                 mTouchX = event.getX();  
  90.                 mTouchY = event.getY();  
  91.             } else {  
  92.                 mTouchX = -1;  
  93.                 mTouchY = -1;  
  94.             }  
  95.             super.onTouchEvent(event);  
  96.         }  
  97.    
  98.         private void drawWall() {  
  99.             SurfaceHolder holder = getSurfaceHolder();  
  100.             Canvas canvas = holder.lockCanvas();  
  101.             drawTime(canvas);  
  102.             drawCross(canvas);  
  103.             holder.unlockCanvasAndPost(canvas);  
  104.    
  105.             mHandler.removeMessages(DRAW);  
  106.             mHandler.sendEmptyMessageDelayed(DRAW, 50);  
  107.         }  
  108.    
  109.         private void drawTime(Canvas c) {  
  110.             Date date = new Date(System.currentTimeMillis());  
  111.             SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  112.             String strDate = sdf.format(date);  
  113.             c.save();  
  114.             c.drawColor(0xff000000);  
  115.             c.drawText(strDate, mLocationX, mLocationY, mPaint);  
  116.             switch (mDirection) {  
  117.             case DIRECTION_1:  
  118.                 mLocationX = mLocationX + STEP_X;  
  119.                 mLocationY = mLocationY - STEP_Y;  
  120.                 if (mLocationY <= SCOPE_TOP) {  
  121.                     mDirection = DIRECTION_2;  
  122.                 }  
  123.                 break;  
  124.             case DIRECTION_2:  
  125.                 mLocationX = mLocationX + STEP_X;  
  126.                 mLocationY = mLocationY + STEP_Y;  
  127.                 if (mLocationX >= SCOPE_RIGHT) {  
  128.                     mDirection = DIRECTION_3;  
  129.                 }  
  130.                 break;  
  131.             case DIRECTION_3:  
  132.                 mLocationX = mLocationX - STEP_X;  
  133.                 mLocationY = mLocationY + STEP_Y;  
  134.                 if (mLocationY >= SCOPE_BOTTOM) {  
  135.                     mDirection = DIRECTION_4;  
  136.                 }  
  137.                 break;  
  138.             case DIRECTION_4:  
  139.                 mLocationX = mLocationX - STEP_X;  
  140.                 mLocationY = mLocationY - STEP_Y;  
  141.                 if (mLocationX <= SCOPE_LEFT) {  
  142.                     mDirection = DIRECTION_1;  
  143.                 }  
  144.                 break;  
  145.             }  
  146.             c.restore();  
  147.         }  
  148.    
  149.         private void drawCross(Canvas c) {  
  150.             if (mTouchX >= 0 && mTouchY >= 0) {  
  151.                 c.drawLine(mTouchX - RADIUS, mTouchY, mTouchX + RADIUS,  
  152.                         mTouchY, mPaint);  
  153.                 c.drawLine(mTouchX, mTouchY - RADIUS, mTouchX,  
  154.                         mTouchY + RADIUS, mPaint);  
  155.             }  
  156.         }  
  157.     }  
  158. }  
  159.    

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548658.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

第十五天实验-VLAN

一&#xff0c;创建VLAN [sw1]vlan batch 2 to 6 [sw2]vlan batch 2 to 6 [sw3]vlan batch 2 to 6 二&#xff0c;通过需求修改接口 SW1&#xff1a; [sw1]int g0/0/2 [sw1-GigabitEthernet0/0/2]port link-type access ---将接口设置为access [sw1-GigabitEthernet0/0/2]…

hcip第17天

1&#xff0c;禁用 --- 1&#xff0c;接口关闭情况下&#xff1b;2&#xff0c;接口禁用生成树协议 2&#xff0c;阻塞 --- 生成树协议激活接口后进入的第一个状态。该状态下&#xff0c;接口只能侦听BPDU&#xff0c;不能转发BPDU和业务帧&#xff0c;也不能学习MAC地址一开始…

账户配置 三: Gmail

书接上文&#xff0c;Gmail也是大家常用的邮件之一&#xff0c;在Windows Phone 7中配置Gmail非常容易。我们来看看怎样快速配置Gmail。 操作&#xff1a; 找到“设置”并点击进入选择“电子邮件和账户”选择“添加账户”选择“Google”填写“邮件地址”和“密码”并点击“登录…

[深入学习C#]LINQ查询表达式详解(1)——基本语法、使用扩展方法和Lambda表达式简化LINQ查询

此文章非原创,转载自诗人江湖老,原文地址 在Git上下载源码   在工程中我们少不了要定义类或者结构去储存数据&#xff0c;这些数据将被临时地储存在内存中&#xff0c;现在我们想要对其完成一些类似于查找、过滤等等常见的任务的时候&#xff0c;我们该如何去做呢&#xff1…

hcip第18天

链路聚合 --- 可以将多个物理接口捆绑成一个逻辑接口&#xff0c;即将N条物理链路聚合为一条逻辑链路。可以在不升级硬件的条件下&#xff0c;达到增加带宽的效果。 我们将逻辑链路&#xff0c;称为聚合链路&#xff0c;在华为设备中称为ETH-TRUNK链路&#xff08;这个技术是针…

x264编码参数大测试:08 subme与指定码率(1000Kbps)

一、测试内容 测试方法—— x264编码参数大测试&#xff1a;索引贴 http://www.cnblogs.com/zyl910/archive/2011/12/14/x264_encode_param.html 测试参数—— subme&#xff1a;9、10、11。设定子像素&#xff08;subpixel&#xff09;运动估计&#xff08;motion estimation&…

第十八天实验-交换综合

配置思路 eth-trunk &#xff1e; 创建vlan &#xff1e; 划分vlan &#xff1e; trunk干道 &#xff1e; STP &#xff1e; SVI &#xff1e; VRRP &#xff1e; DHCP 一&#xff0c;配置eth-trunk SW&#xff11;&#xff1a; [sw1]int Eth-Trunk 0 ---创建…

HCIA第九节课作业

子网划分&#xff1a; 如何去合理的分配地址 总共需要多少个网段&#xff1f; 14个网段 环回接口8个6个 192.168.1.0/14 借4位 192.168.1.0/28 192.168.1.16/28 192.168.1.32/28 192.168.1.48/28 可用地址数量是多少?14个地址 子网划分第多少位的时候,只有两个可…

如何下载防盗链的歌曲?

初音&#xff0c;大家都很熟悉了。它是YAHAMA&#xff08;雅马哈&#xff0c;就是生产电子琴的那个公司&#xff09;推出的音乐编辑软件vocaloid的一款产品。 1月27号&#xff08;春节放假回来的前一天&#xff09;就要推出vocaloid 3啦&#xff01;&#xff01; 很喜欢IA的《鸟…

如何发布.Net MVC 网站项目(攻略集锦)

转载自诗人江湖老&#xff0c;原文地址 参考文献既然是攻略&#xff0c;就必然有参考文献&#xff0c;放在文章开头&#xff0c;以示敬意&#xff01; 1.MVC项目发布步骤 2.未能从程序集加载“System.ServiceModel.Activation.HttpModule” 3. Win7 IIS 另一个程序正在使用此…

ssh建立原理 及配置两台主机的远程连接实现免密登陆

一、SSH是什么&#xff1f;具体的实现有哪些&#xff1f; SSH是一种协议标准 SSH是用在安全远程登录以及其它安全网络服务 二、SSH原理&#xff1a; SSH为Secure Shell的缩写&#xff0c;默认端口22&#xff0c;由IETF的网络小组&#xff08;Network Working Group&…

常用 SQL Server 规范集锦

原文地址 常见的字段类型选择   &#xff11;.字符类型建议采用varchar/nvarchar数据类型   &#xff12;.金额货币建议采用money数据类型   &#xff13;.科学计数建议采用numeric数据类型   &#xff14;.自增长标识建议采用bigint数据类型 (数据量一大&#xff…

Linux服务器搭建----Web服务器(apache)

WWW的介绍 万维网&#xff08;亦作“Web”、“WWW”、“W3”&#xff0c;英文全称为“World Wide Web”&#xff09;&#xff0c;是一个由许多互相链接的超文本组成的系统&#xff0c;通过互联网访问。在这个系统中&#xff0c;每个有用的事物&#xff0c;称为一样“资源”&…

F5 配置手册 -F5 BIG-IP 10.1-1-激活

F5 配置手册 F5 BIG-IP 10.1-1-激活 统一沟通(中国)有限公司 2012-01-29 前言&#xff1a; F5---太贵! 不过你如果有命运看到这个文章,F5也就不值钱了。 因为:F5提供测试版的虚拟机,我们买不起,总应该玩得起吧! 但愿F5提供更多的机会,给别人机会,也是给自己机会。 参照: 你也可…

Beginning iCloud in iOS 5 Tutorial Part 2(转载)

原文地址&#xff1a;http://www.raywenderlich.com/6031/beginning-icloud-in-ios-5-tutorial-part-2 Setting Up the User Interface The Xcode project template we chose already set up an empty view controller for us. We will extend it by adding the current docume…

JQuery Datatables 服务端分页简单应用学习

背景介绍 最近在一个简单小项目中碰到需要一个前端数据表格控件&#xff0c;在看了网上的资料后最终选择了JQuery Datatables。Datatables功能及其强大&#xff0c;基本满足我的所有需求&#xff0c;在加上其插件Editor具有inline模式&#xff0c;很多需要直接修改数据的功能不…

Java API 设计清单

为什么80%的码农都做不了架构师&#xff1f;>>> 在设计Java API的时候总是有很多不同的规范和考量。与任何复杂的事物一样&#xff0c;这项工作往往就是在考验我们思考的缜密程度。就像飞行员起飞前的检查清单&#xff0c;这张清单将帮助软件设计者在设计Java API的…

利用FSMT进行文件服务器迁移及整合

当企业文件服务器&#xff08;DFS、共享文件夹等&#xff09;面临硬件更新、系统升级或文件服务器合并的情况时&#xff0c;往往会出现不确定的文件丢失、需要重新设置所有权限、无法将多个文件服务器集成到一台服务器上等问题&#xff0c;为了保证文件服务器的数据完整以及权限…

RHEL 6上KVM的安装配置及使用-将物理接口桥接到桥接器

作业环境服务器端操作系统&#xff1a;Red Hat Enterprise Linux Server release 6.0 (Santiago)KVM&#xff1a;qemu-kvm-0.12.1.2-2.113.el6.x86_64 客户端操作系统&#xff1a;Windows 7KVM管理工具&#xff1a;Xming 6.9 一、安装KVM及相关软件 1、KVM 需要有 CPU 的支持&a…

C#中IEnumerableT.Distinct()将指定实体类对象用Lambda表达式实现多条件去重

背景说明 在EF等ORM框架中需要以List实体类的方式对数据进行大量操作&#xff0c;其中免不了对一些数据进行去重复&#xff0c;而C#中IEnumerable.Distinct()便提供了这一功能。只是对刚开始接触的新人来说比价抽象难以接受&#xff0c;本文会对这一功能进行简要说明&#xff…