Reputation: 35
How to create a simple live wallpaper using animated .gif image? I'm getting .gif image not proportioned to the screen. How to make it centercrop?
Upvotes: 2
Views: 1545
Reputation: 941
In my opinion the selected answer is somewhat incomplete and not generic as it mentions hard coded values and doesn't keep in mind different screen sizes. It would be much easier to just get the values sent by onSurfaceChanged method and to use them to scale the Canvas object.
Basically, we take the ratio of the screen width to the movie(GIF) width and the ratio of the screen height to the movie height. These two variables are then used to scale the canvas to fill across the screen perfectly.
Firstly, store the width and height you get from onSurfaceChanged method globally.
@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 runs right after onCreate runs so don't worry, the values will be stored in variables width and height before they are used.
Later when you are initializing the canvas, scale it by using the ratio of the screen size to the movie size. PS - movie is a Movie object associated with the GIF we are working with.
float x = (float)width / (float)movie.width();
float y = (float)height / (float)movie.height();
canvas.scale(x,y);
Upvotes: 0
Reputation: 378
Your activity file
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);
}
}
}
Manifest file
<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>
Create xml directory under res and wallpaper.xml inside it.
<?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>
Make sure you place the gif image inside assets folder. To create an asset folder click on file->New->Folder->assets
Upvotes: 1