Как создать простой живые обои с использованием анимированного изображения .gif? Я получаю .gif изображение не пропорционально экрану. Как сделать его центральным?Живые обои с использованием анимированного gif (с центральным масштабом)
ответ
Файл деятельности
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>
Создание каталога 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 в папку с ресурсами. Чтобы создать папку с активами, щелкните по файлу-> Создать-> Папка-> активы
Он работает. Но для разных устройств изображение не поддерживается должным образом. –
istead of canvas.scale (2f, 2f); try DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager(). GetDefaultDisplay(). GetMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; –
@VarunPuravankara Метод был бы полезен, да. Но было бы немного сложно использовать без предоставления контекста. Более того, поверхность экрана, на котором мы рисуем, может измениться, например, вращение или мультимонитор и т. Д. Таким образом, использование значений, переданных onSurfaceChanged, может помочь. Посмотрите на мой ответ для разъяснения. – SanVed
На мой взгляд, выбранный ответ несколько неполный и не является общим, поскольку он упоминает жестко закодированные значения и не имеет в виду разные размеры экрана. Было бы намного проще получить значения, отправленные методом onSurfaceChanged, и использовать их для масштабирования объекта Canvas.
В основном мы принимаем соотношение ширины экрана и ширины фильма (GIF) и отношение высоты экрана к высоте видео. Эти две переменные затем используются для масштабирования холста, чтобы полностью заполнить экран.
Во-первых, храните ширину и высоту, исходящую от метода 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 работает, так что не волнуйтесь, значения будут сохранены в переменных ширина и высоты, прежде чем они используются.
Позже, когда вы инициализируете холст, масштабируйте его, используя соотношение размера экрана и размера фильма. PS - фильм - это объект Movie, связанный с GIF, с которым мы работаем.
float x = (float)width/(float)movie.width();
float y = (float)height/(float)movie.height();
canvas.scale(x,y);
theres xml property scaleType. , Ты это пробовал? – Sanoop
и ваш вопрос и название разные .. так что измените название пожалуйста .. – Sanoop
Я пробовал без использования файла activity_main.xml. Так что для .gif я не мог использовать scalType программно. –