效果图

博客地址: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相关推荐

  1. Android源码之动态壁纸引擎

    动态壁纸蛮好玩的,也没接触过,看官方有就拿了学习下,是第一次接触引擎Engine,激动兴奋...效果做出来了,记录笔记,吼吼,跟大家交流学习, 废话不多说了,先看效果,再看源码,供大家交流学习,今天的 ...

  2. Android 10.0WallpaperPicker2添加动态壁纸服务

    1.概述 在10.0的系统产品开发中,在定制化开发中,由于需要动态壁纸,而系统自带的只有默认的静态壁纸, 所以需要添加动态壁纸的功能 2.WallpaperPicker2添加动态壁纸服务的核心类 pa ...

  3. android 7.1 壁纸路径,android 7.1 默认动态壁纸

    最近客户提了个需求:升级后默认使用动态壁纸. 但是根据网络资料大量修改动态壁纸的都是修改frameworks/base/core/res/res/values/config.xml文件中 defaul ...

  4. Android超人气系列动态壁纸下载(免费)

    欢迎下载哦: 2011黑丝美腿宝贝喷血写真:http://apk.gfan.com/Product/App213027.html 触摸美女第一季: http://apk.gfan.com/Produc ...

  5. Android自定义壁纸预览界面,Android自定义动态壁纸开发(时钟)

    看到有些手机酷炫的动态壁纸,有没有好奇过他们是如何实现的,其实我们自己也可以实现. 先看效果 上图是动态壁纸钟的一个时钟. 我们先来看看 Livewallpaper(即动态墙纸)的实现,Android ...

  6. android动态壁纸是什么格式的,为什么动态壁纸为APK格式? -

    动态壁纸需要安装,并且apk格式是Android的一种特殊应用程序格式. 动态壁纸相当于一个应用程序,当然,apk ps: 不要说您被用作计算机桌面和屏幕保护程序. . . 您使用的是akp格式,当然 ...

  7. Android研究学习动态壁纸

    1. 创建一个类集成 WallpaperService public class MyWallpaperService extends WallpaperService {@Overridepubli ...

  8. Android 动态壁纸 Livepaper

    动态壁纸原理 及 例子 最近做动态壁纸的项目,原来觉得动态壁纸是个很小的项目,但是看到Android Market上有个专门的动态壁纸分类(现在升级为Google Play了), 而且自己做的这个项目 ...

  9. Android 设置动态壁纸没有确认按钮处理方式

    使用反射设置壁纸, //        wallpaperManager.setWallpaperComponent(new ComponentName(context.getPackageName( ...

最新文章

  1. 华为UPS“内外”兼修
  2. 从最小二乘法到卡尔曼滤波
  3. linux启动顺序怎么修改,怎样修改启动顺序?
  4. promise存在的意义分析resolve reject catch
  5. Qt多线程编程的主要线程类
  6. Android之网络编程
  7. 没有新芯片,没有“大核弹”,黄教主这次给大家带来了个PRADA
  8. android ndk 智能指针,智能指针与弱引用详解
  9. html5 canvas移动位置,HTML5 Canvas 移动
  10. git相关常用基本用法命令及分支操作指南命令
  11. rs422 波特率高错误_质量流量计的应用问题与常见错误代码的故障处理
  12. 基于LAMP的cacti安装和配置问题处理(一)
  13. 【DataMagic】如何在万亿级别规模的数据量上使用Spark
  14. 自动劫持root密码
  15. 数控直线工作台直线控制系统的simulink仿真
  16. 线程、协程、Goroutine的区别和联系
  17. 文字发光_PS教程来喽,看PS大神如何使用PS制作发光字效果,果断收藏一下
  18. php采标教程,国内液压与气动行业标准大全
  19. keil安装及mdk
  20. Pokémon Army (easyversion) -每天一把CF - 20201007

热门文章

  1. geant4构造粒子_Geant4 入射粒子设置
  2. 人生三十年碎语---不同人生阶段的感悟,呵呵
  3. Java各类日志门面(slf4j,commons-logging)和日志框架(log4j,logback)联系和区别
  4. docker容器重启
  5. 大批量更新数据mysql批量更新的四种方法
  6. 分析智能代还软件到底好用吗?靠不靠谱呢?
  7. SSH框架之Spring第二篇
  8. 布局春节和情人节,知乎好物带货10年可玩
  9. android获取设备唯一ID方法
  10. 长志气戒傲气 必须时刻保持冷静