2011-12-30 7 views
8

Desidero ingrandire gli oggetti ListView appena aggiunti con un bell'effetto. Ho pensato che fosse semplice & facile, ma mi sono accontentato di un problema:TransitionDrawable: esegue automaticamente l'inversione della transizione una volta completata

Voglio riprodurre l'animazione TransitionDrawable e una volta completato - riavvolgilo. Il nuovo oggetto sarà highlited per un momento, quindi si fonderà con il resto.

TransitionDrawable dispone di metodi per riprodurre l'animazione in avanti e all'indietro, ma nessuna che potrebbe essere utilizzata per la sincronizzazione. Mi aspettavo una possibilità di specificare una funzione di callback per il completamento di animazione, qualcosa come:

TransitionDrawable transition = (TransitionDrawable) view.getBackground(); 
transition.startTransition(500, new TransitionCompleteListener(){ 
       public void completed() 
       { 
        transition.reverseTransition(500); 
       } 
     }); 

Ma niente di tutto questo è supportato dalla classe di TransitionDrawable.

Il problema è: come si gioca all'animazione TransitionDrawable e, al termine, si riproduce immediatamente all'indietro? Ho avuto l'idea di usare la classe Timer per ritardare l'esecuzione della parte all'indietro dell'animazione, ma questa soluzione sembra un po 'troppo pesante per una cosa così semplice.

O forse dovrei usare qualcosa di diverso da TransitionDrawable? Mi piacerebbe evitare l'uso di animazioni di proprietà, dal momento che voglio supportare i dispositivi più vecchi (e PA sono disponibili da Honeycomb).

risposta

4

Non ho effettivamente provato io stesso ancora, ma Direi che quello che stai mirando potrebbe anche essere possibile con un'animazione Vista vecchio stile, uno tween per essere precisi. Invece di manipolare direttamente il background drawable (supponendo che sia quello che stai facendo attualmente), potresti potenzialmente creare lo stesso effetto cambiando la proprietà alfa di una View che ha esattamente le stesse dimensioni del layout di riga. È quindi possibile specificare sia l'animazione 'normale' sia il suo contrario in un singolo AnimationSet e avere quest'ultimo con un ritardo basato sul primo. In alternativa, l'animazione fornisce uno AnimationListener a cui puoi collegarti e ricevere notifiche quando termina la prima animazione e successivamente iniziare il suo contrario.

Guardando il codice sorgente per TransitionDrawable, vedo anche alcune possibilità per estendere l'implementazione corrente con un'interfaccia listener personalizzata. Non dovrebbe essere troppo difficile rendersi conto del pattern che illustri nello snippet di codice nella tua domanda.

In questo momento sono un po 'in ritardo, quindi mandatemi un commento nel caso in cui abbiate bisogno di ulteriori indicatori concreti (ad esempio frammenti di codice) - cercherò quindi di trovare un po' di tempo questo weekend per aiutarvi.

+0

Hmm ... L'utilizzo di un'interpolazione potrebbe funzionare se si impostasse il colore di sfondo di un'intera ListView sul colore utilizzato per gli elementi di evidenziazione e si impostasse il colore di tutte le righe su bianco. Quindi, manipolando il valore alfa di una riga specifica, otterrei un effetto highliht. ma l'idea di sottoclasse TransitionDrawable sembra migliore, più pulita e solo più "giusta". Ho guardato la fonte ora e sembra abbastanza facile implementare ciò di cui ho bisogno. Aggiornerò la mia domanda con una soluzione quando la codificherò, ora ho bisogno di tornare alla mia tesi di laurea (non legata a questo ofc - è un progetto di hobby). Vinci la taglia. – user1234567

-2

analizzare completamente utilizzando ViewAnimator invece http://developer.android.com/reference/android/widget/ViewAnimator.html

Il dentro e fuori oggetto di animazione attaccato al ViewAnimator avere un AnimationListener che fa scattare l'evento che si desidera catturare

+0

posso sbagliarmi -, ma non è ViewAnimator abituato a passare da una vista (come in ViewFlipper, che è è sottoclasse)? – user1234567

+0

sì e il mio suggerimento sarebbe di avere due punti di vista; uno normale e uno evidenziato. Fondamentalmente, per il tuo elenco di righe xml, hai ViewAnimator come elemento esterno e i suoi figli sono gli stessi della tua lista corrente. Quindi, quando viene aggiunto un elemento che si desidera mettere a fuoco, attraverso il codice si aggiunge una nuova vista a ViewAnimator e si avvia la transizione alla vista che rappresenta lo stato evidenziato. Si imposta un listener di eventi e si acquisisce l'evento al termine e si inverte l'azione. – dparnas

0

Forse si potrebbe provare questo:

Drawable[] transBack = new Drawable[] { res.getDrawable(R.drawable.ic_acept_blue), res.getDrawable(R.drawable.ic_acept)}; 

ImageView btn = (ImageView) findViewById(R.id.resource); 
TransitionDrawable transitionAcept = new TransitionDrawable(transBack); 
btn.setImageDrawable(transitionAcept); 

btn.setOnTouchListener(new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     // TODO Auto-generated method stub 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_DOWN:{ 
      TransitionDrawable transition = (TransitionDrawable) btn.getDrawable(); 
      transition.startTransition(75); 
     }break; 
     case MotionEvent.ACTION_UP:{ 
      TransitionDrawable transition = (TransitionDrawable) btnAcept.getDrawable(); 
      transition.reverseTransition(75); 
      v.performClick(); 
     }break; 
     default: 
     break; 
    } 
    return true; 
} 
}); 
btn.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     //... DO Something here 
    } 
}); 

Il codice di cui sopra implementa un TouchListener per gestire inversione e di transizione in avanti, e un clickListener per gestire le vostre azioni. Ecco perché nel MotionEvent.ACTION_UP chiami per v.performClick(); Spero che questo ti aiuti.

0

Ho esteso l'implementazione di TransitionDrawable (effettivamente copiato e modificato) per accettare un parametro repeatCount che indica quante volte effettuare la transizione avanti e indietro. Vedere lo RepeatableTransitionDrawable nel repository sottostante.

Ho anche in programma di aggiungere più di due supporti estraibili.

https://github.com/mehmet6parmak/CustomDrawables

0

prova con un Handler;)

final TransitionDrawable transition = (TransitionDrawable) sizesSelectionLayout.getBackground(); 
int duration = 500; 
transition.startTransition(duration); 
new Handler().postDelayed(new Runnable() { 
    @Override 
    public void run() { 
     transition.reverseTransition(duration); 
    } 
}, duration); 

;)

Problemi correlati