Ich hatte die Möglichkeit, eine "Look like Floating" -Animation auf Android zu implementieren. Es sieht aus wie das folgende Bild.
Diese Animation
Wird durch Ausführen von "kontinuierlich" und "wiederholt" realisiert. "Kontinuierlich" bedeutet, dass nach Abschluss der Animation von 1. die Animation von 2. gestartet wird.
Dies mit der View-Animations-API von Android zu tun, ist normalerweise schrecklicher Code. Als nächstes kommt das.
//Animation, die sich über 2 Sekunden nach oben bewegt
final TranslateAnimation anim1 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -0.1f);
anim1.setDuration(2000);
//Animation, die sich über 2 Sekunden nach unten bewegt
final TranslateAnimation anim2 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -0.1f,
Animation.RELATIVE_TO_SELF, 0.0f);
anim2.setDuration(2000);
anim1.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
anim2.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
// 3.Wenn die Abwärtsanimation beendet ist, starten Sie die Aufwärtsanimation erneut
view.startAnimation(anim1);
}
@Override
public void onAnimationRepeat(Animation animation) { }
});
// 2.Wenn die Aufwärtsanimation beendet ist, starten Sie die Abwärtsanimation
view.startAnimation(anim2);
}
@Override
public void onAnimationRepeat(Animation animation) { }
});
// 1.Starten Sie die Animation, um nach oben zu gelangen
view.startAnimation(anim1);
Der doppelte Schmerz beim Verschachteln von Rückrufen besteht darin, dass der gewünschte Prozess und die Reihenfolge, in der Sie den Code schreiben, umgekehrt sind, was nicht möglich ist.
Dies ist der einzige Fall, in dem Sie Kotlin verwenden möchten (es ist besser, wenn Sie die Bibliothek
Wie @glayash kommentierte, können Sie, wenn Sie die Animation wie diese wiederholen, wie folgt schreiben, damit sie nicht zur Hölle des Rückrufs wird und Sie Kotlin nicht einmal verwenden mussten.
//Animation, die sich über 2 Sekunden nach oben bewegt
final TranslateAnimation anim1 = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -0.1f);
anim1.setDuration(2000);
//Invertieren und auf unbestimmte Zeit wiederholen
anim1.setRepeatMode(Animation.REVERSE);
anim1.setRepeatCount(Animation.INFINITE);
view.startAnimation(anim1);
Deshalb habe ich es mit Kotlin versucht.
Erstellen Sie zunächst eine "Funktion, die die Animation ausführt und nach Abschluss der Animation mit der nächsten fortfährt".
Hier habe ich es als Erweiterungsfunktion von View
definiert.
package net.amay077.animsample
import android.view.View
import android.view.animation.Animation
import kotlin.coroutines.experimental.suspendCoroutine
suspend fun View.startAnimationAsync(anim: Animation) {
return suspendCoroutine { continuation ->
anim.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation?) { }
override fun onAnimationEnd(animation: Animation?) {
continuation.resume(Unit)
}
override fun onAnimationRepeat(animation: Animation?) { }
})
this.startAnimation(anim)
}
}
Der Anrufer sieht folgendermaßen aus:
Dies ist der Himmel im Vergleich zu Java in Callback Hell ...
Es scheint, dass Sie launch (UI) {}
anstelle von async () {}
verwenden müssen, da die Animation vom UI-Thread aufgerufen werden muss.
val button1 = findViewById(R.id.button1)
val anim1 = TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -0.5f)
anim1.duration = 2000
val anim2 = TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, 0.0f,
Animation.RELATIVE_TO_SELF, -0.5f,
Animation.RELATIVE_TO_SELF, 0.0f)
anim2.duration = 2000
launch(UI) { //Ich werde vom Haupt-Thread asynchronisieren
//Wiederholen Sie die ganze Zeit
while (true) {
button1.startAnimationAsync(anim1) // 1.Führen Sie eine Animation aus, die sich über 2 Sekunden nach oben bewegt
button1.startAnimationAsync(anim2) // 2.Führen Sie eine Animation aus, die sich über 2 Sekunden nach unten bewegt
}
}
Es ist mein erstes Mal, dass ich Kotlin richtig benutze, also kann ich es vielleicht noch verbessern. .. Bitte weisen Sie auf einen guten Code hin.
Für die Implementierung in Kotlin habe ich auf die folgende Site verwiesen
C # (dh Xamarin.Android) kann auch mit einer Kombination aus "async / await (dh Task)" und "TaskCompletionSource" erreicht werden.
C # verfügt auch über eine Erweiterungsmethode, die wie folgt definiert werden kann:
public static class ViewAnimationExtensions
{
public static Task<bool> StartAnimationAsync(this View view, Animation anim)
{
var source = new TaskCompletionSource<bool>();
EventHandler<Animation.AnimationEndEventArgs> handler = null;
handler = (sender, e) =>
{
anim.AnimationEnd -= handler; //Vergessen Sie nicht, sich abzumelden
source.SetResult(true); //Kotlin Fortsetzung.resume(Unit)Toko
};
anim.AnimationEnd += handler; //Abonnieren Sie die Veranstaltung
view.StartAnimation(anim);
return source.Task;
}
}
Dies ist die Startseite.
Fügen Sie beim Aufrufen das Schlüsselwort await
hinzu und fügen Sie der Methode, die es enthält, das Schlüsselwort async
hinzu (hier OnCreate
).
protected async override void OnCreate(Bundle savedInstanceState)
{
/*Kürzung*/
while (true)
{
await button1.StartAnimationAsync(anim1);
await button1.StartAnimationAsync(anim2);
}
}
Es wäre schön, wenn Kotlin im selben Projekt mit Java gemischt werden könnte.
Recommended Posts