2011-12-30 15 views
8

Chcę dodać nowo dodane elementy ListView z dobrym efektem. Pomyślałem, że to proste, ale łatwo natknąłem się na problem:TransitionDrawable: automatyczne przejście do tyłu po ukończeniu

Chcę odtworzyć animację TransitionDrawable, a po jej zakończeniu - przewinąć do tyłu. Nowy przedmiot zostanie na chwilę podświetlony, a następnie zestarzeje się z resztą.

TransitionDrawable ma metody odtwarzania animacji do przodu i do tyłu, ale żadne nie mogą być użyte do synchronizacji. Spodziewałem się możliwość określenia zwrotnego dla realizacji animacji, coś jak:

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

ale nic tak jest obsługiwany przez klasę TransitionDrawable.

Problem polega na tym, jak odtwarzać animację TransitionDrawable, a kiedy się to skończy - natychmiast odtwarzać w tył? Wpadłem na pomysł, aby użyć klasy Timer, aby opóźnić wykonanie części animacji wstecznej, ale to rozwiązanie wygląda nieco zbyt ciężko na tak prostą rzecz.

A może powinienem użyć czegoś innego niż TransitionDrawable? Chciałbym uniknąć używania animacji właściwości, ponieważ chcę obsługiwać starsze urządzenia (a PA są dostępne od czasów Honeycomb).

Odpowiedz

4

ja nie faktycznie próbowałem go sobie jeszcze, ale Powiedziałbym, że cel, do którego dążysz, może być także możliwy dzięki staromodnej animacji View, a konkretnie tween. Zamiast bezpośrednio manipulować rysunkiem tła (zakładając, że właśnie to robisz), możesz potencjalnie stworzyć ten sam efekt, zmieniając właściwość alfa widoku, który ma dokładnie takie same wymiary jak układ wiersza. Następnie można określić zarówno "normalną" animację, jak i jej odwrócenie w pojedynczym zestawie animacji, a następnie rozpocząć od opóźnienia opartego na pierwszej animacji. Alternatywnie, Animacja zapewnia AnimationListener, którą możesz podłączyć i otrzymać powiadomienie, gdy kończy się pierwsza animacja, a następnie rozpocząć jej odwrócenie.

Patrząc na kod źródłowy TransitionDrawable, widzę również pewne możliwości rozszerzenia obecnej implementacji za pomocą niestandardowego interfejsu nasłuchującego. Nie powinno być zbyt trudno uświadomić sobie wzór, który ilustrujesz w fragmencie kodu w pytaniu.

Jestem teraz trochę za krótka, więc napisz do mnie komentarz na wypadek, gdybyś potrzebował więcej konkretnych wskazówek (np. Fragmentów kodu) - spróbuję znaleźć czas w ten weekend, aby ci pomóc.

+0

Hmm ... Używanie animacji może działać, gdybym ustawił kolor tła całego ListView na kolor używany do podświetlania elementów i ustaw kolor wszystkich wierszy na biały. Następnie, manipulując wartością alfa określonego rzędu, osiągnęłbym wysoki efekt. ale pomysł podklasy TransitionDrawable wydaje się lepszy, bardziej czysty i po prostu bardziej "właściwy". Spojrzałem teraz na jego źródło i wydaje się dość łatwe wdrożenie tego, czego potrzebuję. Będę aktualizować moje pytanie rozwiązaniem, kiedy będę je kodować, teraz muszę wrócić do mojej pracy magisterskiej (niezwiązanej z tym ofc - to projekt hobby). Wygrywasz nagrodę. – user1234567

-2

ocenić stosując ViewAnimator zamiast http://developer.android.com/reference/android/widget/ViewAnimator.html

in i na zewnątrz obiektu animacji dołączonej do ViewAnimator mieć AnimationListener która wyzwala zdarzenie, które chcesz uchwycić

+0

Może się mylę - ale nie jest ViewAnimator służy do przełączania się między widokami (jak w ViewFlipper, który jest jego podklasa)? – user1234567

+0

tak i moja sugestia będzie mieć dwa poglądy; jedna normalna i jedna podświetlona. Zasadniczo dla twojego wiersza listy xml masz ViewAnimator jako element zewnętrzny, a jego dzieci są takie same jak twój obecny wiersz listy. Następnie, po dodaniu elementu, który chcesz skupić, możesz przez kod dodać nowy widok do ViewAnimator i rozpocząć przejście do widoku reprezentującego zaznaczony stan. Konfigurujesz detektor zdarzeń i przechwytujesz zdarzenie po jego zakończeniu, a ty odwracasz akcję. – dparnas

0

Może spróbuj tak:

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 
    } 
}); 

Powyższy kod implementuje TouchListener do obsługi przejścia do przodu i do tyłu oraz clickListener do obsługi swoich działań. Dlatego w MotionEvent.ACTION_UP zadzwoń na v.performClick(); Mam nadzieję, że Ci to pomoże.

0

Rozszerzyłem implementację TransitionDrawable (w rzeczywistości skopiowałem ją i zmodyfikowałem), aby zaakceptować parametr repeatCount, który określa, ile razy należy wykonać przejście z powrotem iz powrotem. Zobacz RepeatableTransitionDrawable w repozytorium poniżej.

Planuję również dodać więcej niż dwa obsługiwane rysunki.

https://github.com/mehmet6parmak/CustomDrawables

0

Spróbuj z 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); 

;)

Powiązane problemy