zoukankan      html  css  js  c++  java
  • 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:
    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代码结构如下:
    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就可以完成了。让我们逐个看一下这几个方法的实现。
    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的代码:
      
    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():
            
    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的效果:

    附件代码:
     
     

    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.    
  • 相关阅读:
    C语言第四章
    C第三章,指代数据
    DES+MD5加密
    时间选择器
    百度地图定位
    Httputils请求网络数据
    xStream解析xml文件
    pulltorefresh
    slidingmenu的应用
    Duutils创建数据库
  • 原文地址:https://www.cnblogs.com/sode/p/2318006.html
Copyright © 2011-2022 走看看