2016-03-29 12 views
1

So erstellen Sie eine einfache Live Wallpaper mit animierten .gif Bild? Ich erhalte ein .gif-Bild, das nicht proportional zum Bildschirm ist. Wie macht man es zum Zentrum?Live Wallpaper mit animierten GIF (mit Centercrop ScaleType)

+0

Es gibt eine XML-Eigenschaft scaleType. . Hast du es versucht? – Sanoop

+0

und Ihre Frage und Titel sind anders .. so ändern Sie den Titel bitte .. – Sanoop

+1

Ich habe versucht, ohne activity_main.xml-Datei verwenden. Also für .gif konnte ich scalType nicht programmatisch benutzen. –

Antwort

1

Ihre Aktivitätsdatei

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-Datei

<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> 

unter res und wallpaper.xml Inneren Erstellen von XML-Verzeichnis.

<?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> 

Stellen Sie sicher, das GIF-Bild innerhalb Assets Ordner. Um einen Asset-Ordner zu erstellen, klicken Sie auf Datei-> Neu-> Ordner-> Assets

+0

Es funktioniert. Aber für verschiedene Geräte wird das Bild nicht richtig propotiert. –

+1

anstelle von canvas.scale (2f, 2f); versuchen DisplayMetrics displaymetrics = neue DisplayMetrics(); getWindowManager(). GetDefaultDisplay(). GetMetrics (Anzeigemetriken); int height = displaymetrics.heightPixels; int width = displaymetrics.widthPixels; –

+1

@VarunPuravankara Die Methode wäre nützlich, ja. Aber es wäre ein wenig kompliziert zu verwenden, ohne dass der Kontext bereitgestellt wird. Außerdem könnte sich die Oberflächenansicht des Bildschirms, auf dem wir zeichnen, ändern, wie zum Beispiel Rotation oder Multimonitor usw. Die Verwendung der von onSurfaceChanged übergebenen Werte könnte also helfen. Sehen Sie sich meine Antwort zur Klärung an. – SanVed

0

Meiner Meinung nach ist die ausgewählte Antwort etwas unvollständig und nicht generisch, da sie fest codierte Werte erwähnt und verschiedene Bildschirmgrößen nicht berücksichtigt. Es wäre viel einfacher, die von der onSurfaceChanged-Methode gesendeten Werte abzurufen und sie zum Skalieren des Canvas-Objekts zu verwenden.

Grundsätzlich nehmen wir das Verhältnis der Bildschirmbreite zur Filmbreite (GIF) und das Verhältnis der Bildschirmhöhe zur Filmhöhe. Diese beiden Variablen werden dann verwendet, um die Arbeitsfläche so zu skalieren, dass sie perfekt über den Bildschirm passt.

Speichern Sie zuerst die Breite und Höhe, die Sie von der onSurfaceChanged-Methode erhalten.

@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 läuft direkt nach onCreate läuft also keine Sorge, werden die Werte in Variablen Breite und Höhe gelagert werden, bevor sie verwendet werden.

Wenn Sie die Zeichenfläche später initialisieren, skalieren Sie sie, indem Sie das Verhältnis der Bildschirmgröße zur Filmgröße verwenden. PS - Film ist ein Movie-Objekt, das mit dem GIF verknüpft ist, mit dem wir arbeiten.

float x = (float)width/(float)movie.width(); 
float y = (float)height/(float)movie.height(); 
canvas.scale(x,y);