2017-12-11 2 views
0

Ich brauche wirklich Hilfe, um diese Animation zu beheben. Ich setze eine Animation dynamisch mit addFrame(). Jede generierte Animation besteht aus 5 Frames. Insgesamt sind 5 verschiedene Animationen möglich. Die Animation wird von einem Handler gestartet - alle 5 Sekunden.AnimationDrawable funktioniert nur einmal

setAnimation(); //inital setting of animation 

    stimulusOverlay.setBackground(animation); 

    final Handler recallStimulusHandler = new Handler(); 
    Runnable runAnimation = new Runnable() { 
     @Override 
     public void run() { 
      stimulusOverlay.setVisibility(View.VISIBLE); 
      animation.start(); 
      setStimulusInvisibleHandler(); 
      recallStimulusHandler.postDelayed(this, 5000); 
     } 
    }; 
    stimulusOverlay.post(runAnimation); 

    private void setStimulusInvisibleHandler(){ 
     final Handler setInvisibleHandler = new Handler(); 
     final Runnable setStimulusInvisible = new Runnable() { 
      @Override 
      public void run() { 
       stimulusOverlay.setVisibility(View.INVISIBLE); 
       setAnimation(); 
      } 
     }; 
     setInvisibleHandler.postDelayed(setStimulusInvisible, 2000); 
    } 

Ich muss den Handler verwenden. Andernfalls würden die Frames für die gegebene Zeit nicht angezeigt werden. Nach 2 Sekunden (Animation dauert ca. 1,5 sec) ändere ich die Animation - für die nächste Schleife - mit der Funktion setAnimation().

private void setAnimation() { 

     Resources res = this.getResources(); 
     String stimulusString = getStimulusFromPref(countAnimation); // never empty 
     int stimulusId = res.getIdentifier(stimulusString, "drawable", this.getPackageName()); 
     int stimulusLength = stimulusString.length(); 
     String maskingString = "mask_" + stimulusLength; 
     int maskingId = res.getIdentifier(maskingString, "drawable", this.getPackageName()); 

     AnimationDrawable nextAnimation = new AnimationDrawable(); 
     nextAnimation.setOneShot(true); 
     nextAnimation.addFrame(res.getDrawable(R.drawable.transparent), 300); 
     nextAnimation.addFrame(res.getDrawable(maskingId), 300); 
     nextAnimation.addFrame(res.getDrawable(stimulusId), 300); 
     nextAnimation.addFrame(res.getDrawable(maskingId), 300); 
     nextAnimation.addFrame(res.getDrawable(R.drawable.transparent), 300); 
     animation = nextAnimation; 

     countAnimation = (countAnimation + 1)%5; 
    } 

Der Code läuft zum ersten Mal einwandfrei. Danach taucht nichts mehr auf, ohne eine Ausnahme oder Warnung zu werfen.

Verwenden von Protokollen:

Der Code läuft für jede 5 Sekunden durch

die dynamische Bilderzeugung funktioniert gut (für jede mögliche Kombination)

Ich dachte auch über so etwas wie rekursive Aufrufe an die Ende setAnimation(), aber ich denke, alle 5 Sekunden den Handler aufrufen macht Rekursion ungültig. getResources() gibt immer den gleichen Wert zurück, also denke ich, dass hier alles funktioniert. Ich muss animation mit einer neuen Animation überschreiben, weil es keine Möglichkeit gibt, die Animation wie removeFrames oder etwas ähnliches zurückzusetzen. Es gibt auch einen weiteren Code, der das ImageView sichtbar/unsichtbar macht, aber das ist auch nicht das Problem. ich die Image meiner WINDOW wie folgt ergänzt: (glaube nicht, dass das Problem ist, nur aus Gründen der Vollständigkeit)

windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); 
    stimulusOverlay = new ImageView(this); 
    stimulusOverlay.setVisibility(View.VISIBLE); 

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
      WindowManager.LayoutParams.WRAP_CONTENT, 
      WindowManager.LayoutParams.WRAP_CONTENT, 
      WindowManager.LayoutParams.TYPE_PHONE, 
      WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, 
      PixelFormat.TRANSLUCENT 
    ); 

    windowManager.addView(stimulusOverlay, params); 

Vielleicht haben Sie eine Vorstellung davon, was hier schief geht. Fragen Sie einfach nach weiteren Fragen oder etwas.

+0

Können Sie debuggen, indem Sie Breakpoints setzen, um herauszufinden, was vor sich geht? – Raghunandan

+0

Ich weiß, dass der Code durch jede Zeile läuft. setAnimation() wird alle 5 Sekunden aufgerufen, die Animation hat einen neuen Wert für jeden Aufruf von animation = nextAnimation; Ints und String haben ihre Werte. Ich weiß nicht, wie ich tiefer im Code debuggen kann. – DHdeveloper

Antwort

0

Offensichtlich rufen Sie den Handler nur einmal. Nach der ersten Ausführung Handler wird nicht erneut aufgerufen und es stoppt die Ausführung. Stattdessen Aufruf von sucurusOverlay wieder in Schleife wie folgt.

final Handler recallStimulusHandler = new Handler(); 
Runnable runAnimation = new Runnable() { 
    @Override 
    public void run() { 
     stimulusOverlay.setVisibility(View.VISIBLE); 
     animation.start(); 
     setStimulusInvisibleHandler(); 
     recallStimulusHandler.postDelayed(this, 5000); 
     //call this handler again 
     stimulusOverlay.post(runAnimation); 
    } 
}; 
stimulusOverlay.post(runAnimation); 

Auch setInvisibleHandler.postDelayed(setStimulusInvisible, 2000) innen setStimulusInvisibleHandler() Methode entfernen.

+0

Aber 'this' in postDelayed ruft die' runAnimation' Runnable auf - alle 5 Sekunden? Warum sollte ich die setStimulusInvisibleHandler() Methode entfernen? – DHdeveloper

+0

weil es zweimal aufgerufen wird..wieder innerhalb der Methode setStimulusInvisibleHandler() rufen Sie die Methode auf – Anonymous