2016-03-29 4 views
1

Как создать простой живые обои с использованием анимированного изображения .gif? Я получаю .gif изображение не пропорционально экрану. Как сделать его центральным?Живые обои с использованием анимированного gif (с центральным масштабом)

+0

theres xml property scaleType. , Ты это пробовал? – Sanoop

+0

и ваш вопрос и название разные .. так что измените название пожалуйста .. – Sanoop

+1

Я пробовал без использования файла activity_main.xml. Так что для .gif я не мог использовать scalType программно. –

ответ

1

Файл деятельности

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 в папку с ресурсами. Чтобы создать папку с активами, щелкните по файлу-> Создать-> Папка-> активы

+0

Он работает. Но для разных устройств изображение не поддерживается должным образом. –

+1

istead of canvas.scale (2f, 2f); try DisplayMetrics displaymetrics = new DisplayMetrics(); getWindowManager(). GetDefaultDisplay(). GetMetrics (displaymetrics); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; –

+1

@VarunPuravankara Метод был бы полезен, да. Но было бы немного сложно использовать без предоставления контекста. Более того, поверхность экрана, на котором мы рисуем, может измениться, например, вращение или мультимонитор и т. Д. Таким образом, использование значений, переданных onSurfaceChanged, может помочь. Посмотрите на мой ответ для разъяснения. – SanVed

0

На мой взгляд, выбранный ответ несколько неполный и не является общим, поскольку он упоминает жестко закодированные значения и не имеет в виду разные размеры экрана. Было бы намного проще получить значения, отправленные методом 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);