• 开发实时壁纸


    所谓实时壁纸,即动态壁纸,就是手机桌面不再是简单的图片,而是运行中的动画,该动画由程序实时绘制的,所以称为实时壁纸。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" />





     

  • 相关阅读:
    弹丸类以及魂类的构想
    LaunchCharacter
    如何让Ue4画面产生振动效果
    解决Ue4C++使用UMG之类的模块时出现的拼写错误
    我认为我可以去尝试做一下Maya Ue4导出插件
    Wiki上的Ue4文件结构以及命名规范
    如何在修改了默认值之后跟新
    Ue4 BatteryCollector 教程笔记
    Ue4的GitHUB版本版本管理探索
    FString的相关文档,另外还有4种LOG的方法
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3198933.html
Copyright © 2020-2023  润新知