2015-04-02 5 views
5

Quando si esegue questo codice all'interno della visualizzazione personalizzata, onAnimationStart e onAnimationEnd vengono richiamati ripetutamente. Non è strano? Come programmatore Android, mi aspettavo che fossero chiamati solo una volta rispettivamente.Impossibile rimuovere l'ascoltatore di ViewPropertyAnimator

final ViewPropertyAnimator animator = animate().setDuration(1000).alpha(0.0f); 
    animator.setListener(new AnimatorListenerAdapter() { 
     @Override 
     public void onAnimationStart(Animator animation) { 
      Utils.log("----------------start"); 
     } 

     @Override 
     public void onAnimationEnd(Animator animation) { 
      Utils.log("--------- end"); 
     } 
    }).start(); 

Ma poi ho cercato di risolvere il problema rimuovendo l'ascoltatore quando onAnimationEnd viene chiamato da s setListener(null)ViewPropertyAnimator', ma non ha mai funzionato, nonostante ciò che è scritto nei documenti:

public ViewPropertyAnimator setListener (Animator.AnimatorListener listener) 

Added in API level 12 
Sets a listener for events in the underlying Animators that run the property animations. 

Parameters 
listener The listener to be called with AnimatorListener events. A value of null removes any existing listener. 
Returns 
This object, allowing calls to methods in this class to be chained. 

Qualcun altro ha incontrato questo strano problema? forse è un bug di Android?

+0

dove si chiama animator.start()? – pskink

+0

all'interno della mia vista personalizzata, btw, in realtà penso di non aver nemmeno bisogno di chiamarlo, l'animazione sarà avviata dalla prossima opportunità (forse il prossimo fotogramma). L'ho letto da qualche parte nei documenti – Leo

+0

che cosa significa "all'interno della mia vista personalizzata"? quale metodo? – pskink

risposta

18

Mi sono appena imbattuto in questo problema ma senza la visualizzazione personalizzata.

Nel mio caso, ho avuto due animazioni sulla stessa vista. Uno spettacolo e nascondigli.

Così è stato

showView(){ 
    myView.animate().translationY(myView.getHeight()).setListener(new ...{ 
    ... 
    onAnimationEnd(Animation animation){ 
    hideView(); 
    } 
    ...}).start(); 
} 
hideView(){ 
    myView.animate().translationY(0).start(); 
} 

Quando hideView() finito, sarebbe chiamare se stesso ancora una volta. Questo perché il vecchio ascoltatore era ancora impostato. La chiave per risolverlo è stata quella di impostare il listener su null nella seconda animazione. per esempio.

hideView(){ 
    myView.animate().translationY(0).setListener(null).start(); 
} 
+5

setListener (null) può effettivamente essere chiamato all'interno della callback listener stessa che, rende il codice più ordinato da allora l'ascoltatore pulisce dopo se stesso. –

+0

@SafaAlai Come mai? – Mauker

+0

@Mauker puoi semplicemente usare myView.animate(). SetListener (null); in onAnimationEnd .. Sembra un po 'strano, ma guardando la fonte di Android il metodo animate() restituisce il ViewPropertyAnimator creato in precedenza in modo da ottenere solo quel valore e impostare il listener su null. –