2010-12-28 10 views
4

Ich habe eine App mit Tasten, die verschiedene Frame-by-Frame-Animationen spielen, wenn gedrückt. Die Animationen werden als Sequenzen von .png-Dateien gespeichert. Einige der Animationen füllen einen kleinen Bereich und sie scheinen mit animationDrawable gut zu spielen. Einige der Animationen füllen jedoch einen großen Teil des Bildschirms aus (obwohl sie größtenteils mit einem Alpha-Kanal transparent sind), und ich erhalte einen Speichermangel, wenn die App auf meinem Telefon geladen wird (aber nicht der Emulator). Ich kann sie nicht als Videodateien wiedergeben, da sie den Hauptbildschirm überlagern müssen.Playing große PNG-Frame-Animation in Android mit animationDrawable

Meine Hauptfrage - gibt es eine Möglichkeit, große png Sequenzanimationen (Say 60 Frames bei 320x480) mit animationDrawable zu spielen?

Bis jetzt scheint es in meiner Forschung keinen Weg zu geben, die Speichergrenzen zu umgehen ... also habe ich nach meiner eigenen Methode gesucht, die ein ImageView erstellt und es mit einer Bitmap füllt und dann sukzessive ersetzt die Bitmap mit jedem Frame nach einer Verzögerung. Mit dieser Technik scheint meine Animation jedoch nur die ersten und letzten Frames zu spielen.

Hier ist der Code meines Stabes bei der Verwendung animationDrawable - der "Schimpanse" spielt gut, aber wenn ich die "Blasen" (die größeren Bilder) hinzufügen, lädt die App überhaupt nicht - logCat zeigt: "ERROR/dalvikvm Haufen (3248): 1.008.000 Byte externe Zuordnung zu groß für diesen Prozess ... ERROR/Android Runtime (3248): java.lang.OutOfMemoryError: überschreiten Bitmap-Größe VM Budget "

public class Babymode_tst extends Activity implements OnClickListener{ 
/** Called when the activity is first created. */ 
AnimationDrawable chimpAnimation; 
AnimationDrawable bubblesAnimation; 
private MediaPlayer mp; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    setVolumeControlStream(AudioManager.STREAM_MUSIC); 

    final ImageButton chimpButton = (ImageButton) findViewById(R.id.chimp_button); 
    chimpButton.setOnClickListener(this); 
    ImageView chimpImage = (ImageView) findViewById(R.id.chimp_imageview); 
    chimpImage.setBackgroundResource(R.drawable.chimp_anim); 
    chimpAnimation = (AnimationDrawable) chimpImage.getBackground(); 

    final ImageButton bubblesButton = (ImageButton) findViewById(R.id.bubbles_button); 
    bubblesButton.setOnClickListener(this); 
    ImageView bubblesImage = (ImageView) findViewById(R.id.bubbles_imageview); 
    bubblesImage.setBackgroundResource(R.drawable.bubbles_anim); 
    bubblesAnimation = (AnimationDrawable) bubblesImage.getBackground(); 
} 

public void onClick(View v) { 
    if (mp != null) { 
    mp.release(); 
    } 

    Random generator = new Random(); 
    int randomIndex; 

    switch(v.getId()){ 
    case R.id.chimp_button: 
    randomIndex = (generator.nextInt(2) + 1); 
    if (randomIndex == 1){ 
    mp = MediaPlayer.create(this, R.raw.chimp_1); 
    } 
    if (randomIndex == 2){ 
    mp = MediaPlayer.create(this, R.raw.chimp_2); 
    } 
    mp.start(); 

    chimpAnimation.setVisible(true,true); 
    chimpAnimation.start(); 

    break; 

    case R.id.bubbles_button: 
    randomIndex = (generator.nextInt(3) + 1); 
    if (randomIndex == 1){ 
    mp = MediaPlayer.create(this, R.raw.bubbles_1); 
    } 
    if (randomIndex == 2){ 
    mp = MediaPlayer.create(this, R.raw.bubbles_2); 
    } 
    if (randomIndex == 3){ 
    mp = MediaPlayer.create(this, R.raw.bubbles_3); 
    } 
    mp.start(); 

    bubblesAnimation.setVisible(true,true); 
    bubblesAnimation.start(); 
    break; 
    } 
} 
} 

Und hier ist mein Versuch, die Einzelbilder nacheinander in einem ImageView abzuspielen, aber nur das erste und das letzte Bild:

public void playAnimation(String name){ 
    final ImageView bubblesImageView = (ImageView) findViewById(R.id.bubbles_imageview); 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0003); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); 
    } 
    }, 500); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); 
    } 
    }, 500); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035); 
    } 
    }, 500); 


} 

Jede Hilfe wäre willkommen - danke

Antwort

0

In meiner Firma haben wir das gleiche Problem, wir haben versucht, einen Splash-Screen auf diese Weise zu machen (und es war totale Katastrophe). Wenn Sie eine Animation so schwer haben möchten, generieren Sie Video aus den PNG-Frames (ich denke, dass FFMPEG das kann) und dann das Video abspielen.

+0

danke - ich bin dabei aufzugeben, animationDrawable zu verwenden ... Haben Sie einen Ratschlag zum Schreiben meines eigenen Codes, der sequentiell abgespielt wird Reihe von Bitmaps? (mein Test davon ist oben). Wird diese Technik zu langsam sein? – JoeD

1

Ihre mHandler.postDelayed(new Runnable(){...}); werden alle zur gleichen Zeit z. nach 500 ms angegeben, dass sie entweder durch

nHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); 
    } 
    }, 500); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); 
    } 
    }, 1000); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0035); 
    } 
    }, 1500); 

oder mit jeweils runnable Warteschlange des nächst man nach einem 500 ms nacheinander auszulösen z.B. verzögern

mHandler.postDelayed(new Runnable() { 
public void run() { 
    bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0015); 

    mHandler.postDelayed(new Runnable() { 
    public void run() { 
     bubblesImageView.setImageResource(R.drawable.bubbles_anim_v5_0025); 
     } 
    }, 1000); 
    } 
}, 500); 

Oder Sie könnten eine Reihe von ìnt mit dem R.drawable.xxx Wert konstruieren und alle 500 ms nur um das nächste Bild anzuzeigen.

Verwandte Themen