android 蕾姆gif动态壁纸 demo
效果图
博客地址:http://write.blog.csdn.net/postedit
下载地址:https://github.com/Aiushtha/RemWallpaper/tree/master
在别的地方看到类似的效果 自己仿做了一个 。默认是双击触发动画播放!!
研究大致实现的原理 ,用最近大热的动漫人物作主题
素材是网上找的,感觉还可以做很多有趣的东西(大雾)
gif播放参考gitView核心代码--
/*** Calculate current animation time*/public void updateAnimationTime() {long now = android.os.SystemClock.uptimeMillis();if (mMovieStart == 0) {mMovieStart = now;}int dur = movie.duration();if (dur == 0) {dur = DEFAULT_MOVIE_VIEW_DURATION;}numberOfRemainingPlay = numberOfPlayCount - (now - mMovieStart) / dur;mCurrentAnimationTime = (int) ((now - mMovieStart) % dur);}/*** Draw current GIF frame*/public void drawMovieFrame(Canvas canvas) {if (numberOfRemainingPlay > 0) {updateAnimationTime();mMovieStart = android.os.SystemClock.uptimeMillis() - mCurrentAnimationTime;movie.setTime(mCurrentAnimationTime);canvas.save(Canvas.MATRIX_SAVE_FLAG);canvas.scale(mScale, mScale);movie.draw(canvas, mLeft / mScale, mTop / mScale);canvas.restore();} else {movie.setTime(movie.duration());}}
通过唤醒线程来控制播放 壁纸核心代码:
package priv.lxz.wallpaper.rem;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Movie;
import android.graphics.PorterDuff;
import android.media.MediaPlayer;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.widget.Toast;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;import de.greenrobot.event.EventBus;
import share.DataShare;public class WallpaperSwitcher extends WallpaperService {private int mWidth;private int mHeight;public Handler handler = new Handler();GifCanvas gitCanvas;private boolean isVisible;private boolean isDestop;private boolean isPause;ReentrantLock lock;private Condition condition;Thread thread;//系统状态栏高度private int system_bar_height;private GifShowOption option;private Wallpaper wallpaper;private DataShare dataShare;private MediaPlayer player;private boolean isLog=false;public void onEventMainThread(AppMessageEvent event) {option = (GifShowOption) event.getObj();wallpaper.effect(option);}public void showLog(String str){if(isLog) {Toast.makeText(getBaseContext(), "onCreate", Toast.LENGTH_LONG);}}@Overridepublic Engine onCreateEngine() {// TODO Auto-generated method stubshowLog("onCreate");initOption();if (!EventBus.getDefault().isRegistered(this)) {EventBus.getDefault().register(this);}gitCanvas = new GifCanvas(getResources(), R.raw.rem);player = MediaPlayer.create(this, R.raw.music_b);player.setLooping(false);if(condition!=null) {isDestop = true;//当重新选择壁纸时销毁线程{lock.lock();condition.signalAll();lock.unlock();//直到线程被销毁while (thread != null) {}isDestop = false;}}lock = new ReentrantLock();condition = lock.newCondition();system_bar_height = getStatusHeight(getBaseContext());return wallpaper = new Wallpaper();}private void initOption() {dataShare = DataShare.getInstance(getBaseContext());option = new GifShowOption();option = dataShare.getData(GifShowOption.class);if (option == null) option = GifShowOption.getDefault();}@Overridepublic void onDestroy() {super.onDestroy();isDestop = true;lock.lock();condition.signalAll();lock.unlock();EventBus.getDefault().unregister(this);player.release();lock=null;condition=null;showLog("Destroy");}/*** 获得状态栏的高度** @param context* @return*/public static int getStatusHeight(Context context) {int statusHeight = -1;try {Class clazz = Class.forName("com.android.internal.R$dimen");Object object = clazz.newInstance();int height = Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());statusHeight = context.getResources().getDimensionPixelSize(height);} catch (Exception e) {e.printStackTrace();}return statusHeight;}class Wallpaper extends Engine implements GestureDetector.OnGestureListener {private GestureDetector gestureScanner;public Wallpaper() {thread = new Thread() {@Overridepublic void run() {while (!isDestop) {try {if (isVisible && gitCanvas.getNumberOfRemainingPlay() > 0) {Canvas canvas = null;try {canvas = getSurfaceHolder().lockCanvas();if (canvas != null) {canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);gitCanvas.drawMovieFrame(canvas);setCanvasARGB(canvas);}} finally {if (canvas != null && !isDestop)getSurfaceHolder().unlockCanvasAndPost(canvas);};} else {if (!isDestop) {show();lock.lock();try {condition.await();} catch (InterruptedException e) {e.printStackTrace();}lock.unlock();}}} catch (Exception e) {e.printStackTrace();}}thread = null;}};thread.start();}public void checkPlayMusic() {if (gitCanvas.getNumberOfRemainingPlay() <= 0) {if (option.isPlaySound) {player.start();}}}private void tiggerCheck(int mode) {switch (mode) {case GifShowOption.TRIGGER_MODE_CHECK_SINGLE:if (option.trigger_mode == GifShowOption.TRIGGER_MODE_CHECK_SINGLE) {checkPlayMusic();gitCanvas.resetPlayNumbierOfOne();play();}break;case GifShowOption.TRIGGER_MODE_CHECK_LONG:if (option.trigger_mode == GifShowOption.TRIGGER_MODE_CHECK_SINGLE) {checkPlayMusic();gitCanvas.resetPlayNumbierOfOne();play();}break;case GifShowOption.TRIGGER_MODE_CHECK_DOUBLE:if (option.trigger_mode == GifShowOption.TRIGGER_MODE_CHECK_DOUBLE) {checkPlayMusic();gitCanvas.resetPlayNumbierOfOne();play();}break;}}/*** 计算比例*/private void setCanvasScale(GifCanvas gitCanvas, int mWidth, int mHeight, Movie movie) {if (option != null) {if (option.isAdaptiveHeight) {gitCanvas.setScale(1.0f * mHeight / gitCanvas.getMovie().height());} else if (option.isAdaptiveWidth) {gitCanvas.setScale(1.0f * mWidth / gitCanvas.getMovie().width());} else if (option.isAdaptiveCustomRatio) {gitCanvas.setScale(option.scale);}}}private void setCanvasARGB(Canvas canvas) {if (option != null) {canvas.drawARGB((int) (255 - option.brightness * 0.01f * 255), 0, 0, 0);}}private void effect(GifShowOption option) {if (getSurfaceHolder() != null) {if (mHeight != 0 && mWidth != 0) {if (option.isAdaptiveHeight) {gitCanvas.setScale(1.0f * mHeight / gitCanvas.getMovie().height());} else if (option.isAdaptiveWidth) {gitCanvas.setScale(1.0f * mWidth / gitCanvas.getMovie().width());} else if (option.isAdaptiveCustomRatio) {gitCanvas.setScale(option.scale);}}}float offectTop = option.upperOffset;float offectLeft = option.leftOffset;if (option.isCalculationBarheight) {gitCanvas.setMoveTop(offectTop + system_bar_height);} else {gitCanvas.setMoveTop(offectTop);}gitCanvas.setMoveLeft(offectLeft);show();}@Overridepublic void onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubsuper.onTouchEvent(event);gestureScanner.onTouchEvent(event);}@Overridepublic void onSurfaceCreated(SurfaceHolder holder) {super.onSurfaceCreated(holder);gestureScanner = new GestureDetector(this);}@Overridepublic void onSurfaceDestroyed(SurfaceHolder holder) {super.onSurfaceDestroyed(holder);}boolean isFristChang = false;@Overridepublic void onSurfaceChanged(SurfaceHolder holder, int format,int width, int height) {if (!isFristChang) {mHeight = height;mWidth = width;setCanvasScale(gitCanvas, mWidth, mHeight, gitCanvas.getMovie());;show();}isFristChang = true;super.onSurfaceChanged(holder, format, width, height);}@Overridepublic void onVisibilityChanged(boolean visible) {isVisible = visible;if (visible) {play();} else {}}void show() {Canvas canvas = null;try {canvas = getSurfaceHolder().lockCanvas();if (canvas != null) {canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);gitCanvas.drawMovieFrame(canvas, 0);setCanvasARGB(canvas);}} finally {try {if (canvas != null && !isDestop) getSurfaceHolder().unlockCanvasAndPost(canvas);} catch (Exception e) {}}}public int isDoubleClick = 0;@Overridepublic boolean onDown(MotionEvent motionEvent) {tiggerCheck(GifShowOption.TRIGGER_MODE_CHECK_SINGLE);isDoubleClick++;if (isDoubleClick >= 2) {tiggerCheck(GifShowOption.TRIGGER_MODE_CHECK_DOUBLE);}handler.postDelayed(new Runnable() {@Overridepublic void run() {isDoubleClick = 0;}}, 250);return false;}public void play() {lock.lock();condition.signalAll();lock.unlock();}@Overridepublic void onShowPress(MotionEvent motionEvent) {}@Overridepublic boolean onSingleTapUp(MotionEvent motionEvent) {return false;}@Overridepublic boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}@Overridepublic void onLongPress(MotionEvent motionEvent) {gitCanvas.resetPlayNumbierOfOne();play();}@Overridepublic boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {return false;}}}
android 蕾姆gif动态壁纸 demo相关推荐
- Android源码之动态壁纸引擎
动态壁纸蛮好玩的,也没接触过,看官方有就拿了学习下,是第一次接触引擎Engine,激动兴奋...效果做出来了,记录笔记,吼吼,跟大家交流学习, 废话不多说了,先看效果,再看源码,供大家交流学习,今天的 ...
- Android 10.0WallpaperPicker2添加动态壁纸服务
1.概述 在10.0的系统产品开发中,在定制化开发中,由于需要动态壁纸,而系统自带的只有默认的静态壁纸, 所以需要添加动态壁纸的功能 2.WallpaperPicker2添加动态壁纸服务的核心类 pa ...
- android 7.1 壁纸路径,android 7.1 默认动态壁纸
最近客户提了个需求:升级后默认使用动态壁纸. 但是根据网络资料大量修改动态壁纸的都是修改frameworks/base/core/res/res/values/config.xml文件中 defaul ...
- Android超人气系列动态壁纸下载(免费)
欢迎下载哦: 2011黑丝美腿宝贝喷血写真:http://apk.gfan.com/Product/App213027.html 触摸美女第一季: http://apk.gfan.com/Produc ...
- Android自定义壁纸预览界面,Android自定义动态壁纸开发(时钟)
看到有些手机酷炫的动态壁纸,有没有好奇过他们是如何实现的,其实我们自己也可以实现. 先看效果 上图是动态壁纸钟的一个时钟. 我们先来看看 Livewallpaper(即动态墙纸)的实现,Android ...
- android动态壁纸是什么格式的,为什么动态壁纸为APK格式? -
动态壁纸需要安装,并且apk格式是Android的一种特殊应用程序格式. 动态壁纸相当于一个应用程序,当然,apk ps: 不要说您被用作计算机桌面和屏幕保护程序. . . 您使用的是akp格式,当然 ...
- Android研究学习动态壁纸
1. 创建一个类集成 WallpaperService public class MyWallpaperService extends WallpaperService {@Overridepubli ...
- Android 动态壁纸 Livepaper
动态壁纸原理 及 例子 最近做动态壁纸的项目,原来觉得动态壁纸是个很小的项目,但是看到Android Market上有个专门的动态壁纸分类(现在升级为Google Play了), 而且自己做的这个项目 ...
- Android 设置动态壁纸没有确认按钮处理方式
使用反射设置壁纸, // wallpaperManager.setWallpaperComponent(new ComponentName(context.getPackageName( ...
最新文章
- 华为UPS“内外”兼修
- 从最小二乘法到卡尔曼滤波
- linux启动顺序怎么修改,怎样修改启动顺序?
- promise存在的意义分析resolve reject catch
- Qt多线程编程的主要线程类
- Android之网络编程
- 没有新芯片,没有“大核弹”,黄教主这次给大家带来了个PRADA
- android ndk 智能指针,智能指针与弱引用详解
- html5 canvas移动位置,HTML5 Canvas 移动
- git相关常用基本用法命令及分支操作指南命令
- rs422 波特率高错误_质量流量计的应用问题与常见错误代码的故障处理
- 基于LAMP的cacti安装和配置问题处理(一)
- 【DataMagic】如何在万亿级别规模的数据量上使用Spark
- 自动劫持root密码
- 数控直线工作台直线控制系统的simulink仿真
- 线程、协程、Goroutine的区别和联系
- 文字发光_PS教程来喽,看PS大神如何使用PS制作发光字效果,果断收藏一下
- php采标教程,国内液压与气动行业标准大全
- keil安装及mdk
- Pokémon Army (easyversion) -每天一把CF - 20201007