使用动画 gif 的动态壁纸(使用 centercrop scaletype)
Live wallpaper using animated gif ( with centercrop scaletype)
如何使用动画 .gif 图片创建简单的动态壁纸?我得到的 .gif 图像与屏幕不成比例。如何使它成为 centercrop?
您的 activity 文件
public class GIFWallpaperService extends WallpaperService {
@Override
public WallpaperService.Engine onCreateEngine() {
try {
Movie movie = Movie.decodeStream(
getResources().getAssets().open("owlinsnow.gif"));
return new GIFWallpaperEngine(movie);
}catch(IOException e){
Log.d("GIF", "Could not load asset");
return null;
}
}
private class GIFWallpaperEngine extends WallpaperService.Engine {
private final int frameDuration = 20;
private SurfaceHolder holder;
private Movie movie;
private boolean visible;
private Handler handler;
public GIFWallpaperEngine(Movie movie) {
this.movie = movie;
handler = new Handler();
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
this.holder = surfaceHolder;
}
private Runnable drawGIF = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
if (visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
// Adjust size and position so that
// the image looks good on your screen
canvas.scale(2f, 2f);
movie.draw(canvas, -100, 0);
canvas.restore();
holder.unlockCanvasAndPost(canvas);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
handler.removeCallbacks(drawGIF);
handler.postDelayed(drawGIF, frameDuration);
}
}
@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
handler.post(drawGIF);
} else {
handler.removeCallbacks(drawGIF);
}
}
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawGIF);
}
}
}
清单文件
<application android:allowBackup="true" android:label="@string/app_name"
android:icon="@drawable/owl" android:theme="@style/AppTheme">
<service
android:name=".GIFWallpaperService"
android:enabled="true"
android:label="Owl in Snow"
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/wallpaper" >
</meta-data>
</service>
</application>
<uses-feature
android:name="android.software.live_wallpaper"
android:required="true" >
</uses-feature>
在 res 下创建 xml 目录并在其中创建 wallpaper.xml。
<?xml version="1.0" encoding="UTF-8"?>
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="GIF Wallpaper"
android:thumbnail="@drawable/owl">
</wallpaper>
确保将 gif 图像放在 assets 文件夹中。要创建资产文件夹,请单击文件->新建->文件夹->资产
在我看来,所选答案有些不完整且不通用,因为它提到了硬编码值并且没有记住不同的屏幕尺寸。只获取 onSurfaceChanged 方法发送的值并使用它们来缩放 Canvas 对象会容易得多。
基本上,我们取屏幕宽度与电影(GIF) 宽度的比例和屏幕高度与电影高度的比例。然后使用这两个变量来缩放 canvas 以完美地填充整个屏幕。
首先,全局存储从 onSurfaceChanged 方法获得的宽度和高度。
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
this.width = width;
this.height = height;
//GLOBALLY DECLARED
}
onSurfaceChanged 在 onCreate 运行之后立即运行,所以不用担心,这些值将在它们运行之前存储在变量 width 和 height 中用过。
稍后当您初始化 canvas 时,使用屏幕尺寸与影片尺寸的比例对其进行缩放。
PS - 电影是与我们正在使用的 GIF 关联的电影对象。
float x = (float)width / (float)movie.width();
float y = (float)height / (float)movie.height();
canvas.scale(x,y);
如何使用动画 .gif 图片创建简单的动态壁纸?我得到的 .gif 图像与屏幕不成比例。如何使它成为 centercrop?
您的 activity 文件
public class GIFWallpaperService extends WallpaperService {
@Override
public WallpaperService.Engine onCreateEngine() {
try {
Movie movie = Movie.decodeStream(
getResources().getAssets().open("owlinsnow.gif"));
return new GIFWallpaperEngine(movie);
}catch(IOException e){
Log.d("GIF", "Could not load asset");
return null;
}
}
private class GIFWallpaperEngine extends WallpaperService.Engine {
private final int frameDuration = 20;
private SurfaceHolder holder;
private Movie movie;
private boolean visible;
private Handler handler;
public GIFWallpaperEngine(Movie movie) {
this.movie = movie;
handler = new Handler();
}
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
super.onCreate(surfaceHolder);
this.holder = surfaceHolder;
}
private Runnable drawGIF = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
if (visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
// Adjust size and position so that
// the image looks good on your screen
canvas.scale(2f, 2f);
movie.draw(canvas, -100, 0);
canvas.restore();
holder.unlockCanvasAndPost(canvas);
movie.setTime((int) (System.currentTimeMillis() % movie.duration()));
handler.removeCallbacks(drawGIF);
handler.postDelayed(drawGIF, frameDuration);
}
}
@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
handler.post(drawGIF);
} else {
handler.removeCallbacks(drawGIF);
}
}
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawGIF);
}
}
}
清单文件
<application android:allowBackup="true" android:label="@string/app_name"
android:icon="@drawable/owl" android:theme="@style/AppTheme">
<service
android:name=".GIFWallpaperService"
android:enabled="true"
android:label="Owl in Snow"
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/wallpaper" >
</meta-data>
</service>
</application>
<uses-feature
android:name="android.software.live_wallpaper"
android:required="true" >
</uses-feature>
在 res 下创建 xml 目录并在其中创建 wallpaper.xml。
<?xml version="1.0" encoding="UTF-8"?>
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:label="GIF Wallpaper"
android:thumbnail="@drawable/owl">
</wallpaper>
确保将 gif 图像放在 assets 文件夹中。要创建资产文件夹,请单击文件->新建->文件夹->资产
在我看来,所选答案有些不完整且不通用,因为它提到了硬编码值并且没有记住不同的屏幕尺寸。只获取 onSurfaceChanged 方法发送的值并使用它们来缩放 Canvas 对象会容易得多。
基本上,我们取屏幕宽度与电影(GIF) 宽度的比例和屏幕高度与电影高度的比例。然后使用这两个变量来缩放 canvas 以完美地填充整个屏幕。
首先,全局存储从 onSurfaceChanged 方法获得的宽度和高度。
@Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
super.onSurfaceChanged(holder, format, width, height);
this.width = width;
this.height = height;
//GLOBALLY DECLARED
}
onSurfaceChanged 在 onCreate 运行之后立即运行,所以不用担心,这些值将在它们运行之前存储在变量 width 和 height 中用过。
稍后当您初始化 canvas 时,使用屏幕尺寸与影片尺寸的比例对其进行缩放。 PS - 电影是与我们正在使用的 GIF 关联的电影对象。
float x = (float)width / (float)movie.width();
float y = (float)height / (float)movie.height();
canvas.scale(x,y);