Android Animation erst komplett ausführen

missy72

Bekanntes Mitglied
Hi, Im Grunde ist es die gleich Frage vom letzten mal, nur in einer anderen Anwendung.
Ich versuche mein Problem diesmal besser zu beschreiben.
Ich habe ein TikTakToe Spiel programmiert. Man spielt gegen eine KI. Hat man seine Zug gewählt, klickt man auf das entsprechende Feld und eine spezifische PlayerMünze wird mit einer Animation aufgedeckt. Nun ist die KI so schnell, dass die Animation der KI-Münze, quasi Zeitgleich mit der PlayerMünze umgedreht wird. Ich hätte gerne, dass erst nach Abschluss der PlayerMünzenAnimation das Programm mit der KI-Funktion weiterläuft.
Natürlich habe sowas wie Thread.sleep, oder eine Schleife mit einem TimeStamp schon ausprobiert. Leider wird in dieser Zeit auch die PlayerMünzenAnimation nicht weiter ausgeführt, sodass sich am Ende immer zwei Münzen, Player und KI, gleichzeitig umdrehen. Blöd.

In diesen Beispiel, wird erst nach verlassen der Schleife in Animation ausgeführt.
Die Logik dahinter verstehe ich überhaupt nicht.

Java:
        imageView.animate().alpha(1).rotationY(360).setDuration(1000);

        long timestamp = System.currentTimeMillis()+2000;
        while (System.currentTimeMillis() < timestamp){
            System.out.println("Bitte warten....");
        }

Schon mal danke für die Hilfe.
VG Maik

PS: Warum das mit dem Thread.sleep nicht funktioniert ist mir klar.
 
Zuletzt bearbeitet:

KonradN

Super-Moderator
Mitarbeiter
Der Aufruf animate() gibt ein ViewPropertyAnimator zurück. Wenn Du diesen nutzen willst, dann kannst Du da die Methode withEndAction nutzen um anzugeben, was danach gemacht werden soll.

Und generell merken: NIE ein active wait machen - so eine Schleife erreicht nur eines: Das man dir auf die Finger haut!

Edit: Mit dem ersten Text war ich nicht zufrieden und daher hatte ich vor dem Absenden alles noch einmal neu geschrieben. Dabei ist aber eine Info entfallen: In Deinem Code fehlt noch ein start() - mit dem angegebenen Code dürfte nichts an Animationen passieren :) Aber das hast Du vermutlich schlicht vergessen mit zu kopieren.
 

missy72

Bekanntes Mitglied
Hi. Das werde ich mal versuchen umzusetzen.

Ein "start()" habe ich aber nicht im Code, aber die Animation läuft.
Als Basis für die Grafik habe ich AndroidStudio eine XML erzeugt und der Code für den Player sieht so aus.
Die Grundlagen habe ich aus einem veralteten Udemy-Android_8 Kurs.
Aber meine App läuft einwandfrei, bis auf der Teil den ich beschrieben hatte.


Java:
    public void turnPlayer(View view) {

        if (!isGameActiv) return;

        ImageView imageView = (ImageView) view;

        String setField = imageView.toString();
        setField = "" + setField.charAt(setField.length()-2);
        int isField = Integer.parseInt(setField);
        int yField = isField / 3;
        int xField = isField - yField * 3;

        if (spielfeld[xField][yField] != 0) return;

        imageView.setImageResource(playerCoin[playerActiv]);
        imageView.animate().alpha(1).rotationY(360).setDuration(1000);

        spielfeld[xField][yField] = playerActiv;

        if (checkGameOver() != 99) return;

        changePlayerKI();
        turnKI();

    }
 

missy72

Bekanntes Mitglied
Ja supi, It`s works. Bin immer wieder von Dir begeistert. @KonradN
Vielen Dank.

Java:
    public void turnPlayer(View view) {

        if (!isGameActiv) return;

        ImageView imageView = (ImageView) view;

        String setField = imageView.toString();
        setField = "" + setField.charAt(setField.length()-2);
        int isField = Integer.parseInt(setField);
        int yField = isField / 3;
        int xField = isField - yField * 3;


        if (spielfeld[xField][yField] != 0) return;

        imageView.setImageResource(playerCoin[playerActiv]);

        imageView.animate().alpha(1).rotationY(360).setDuration(1000).withEndAction(new Runnable() {
            @Override
            public void run() {

                spielfeld[xField][yField] = playerActiv;

                if (checkGameOver() != 99) return;
                changePlayerKI();

                turnKI();

            }
        });
 

KonradN

Super-Moderator
Mitarbeiter
Ein "start()" habe ich aber nicht im Code, aber die Animation läuft.
Ok, das irritiert mich gerade etwas, da ich die Dokumentation anders verstanden habe, aber ok. Wenn es funktioniert, dann ist es ja super :)

Bin immer wieder von Dir begeistert. @KonradN
Das freut mich - wobei ich dazu sagen muss, dass ich von Android eigentlich keine Ahnung habe und damit nur einmal eine App geschrieben habe (vor 4 oder 5 Jahren).

Bezüglich dem Code evtl. noch ein paar kleine Hinweise, die den Code besser lesbar machen:

Pack die run Methode in die eigentliche Klasse und benenne sie sinnvoll. Was weiss ich - finishPlayerMove oder so. Halt ein Name, dass deutlich wird, was die Methode macht.

Und dann wird der Aufruf (Mit Aufteilung in mehrere Zeilen) zu:
Java:
imageView.animate()
    .alpha(1)
    .rotationY(360)
    .setDuration(1000)
    .withEndAction(this::finishPlayerMove);

Statt der Methodenreferenz om .withEndAction(this::finishPlayerMove); kannst Du da auch eine Lambda Expression nutzen: .withEndAction( () -> finishPlayerMove() );

Egal ob Du die Methodenreferenz oder die Lambda Expression bevorzugst: Der Code wird deutlich lesbarer - alleine schon durch den Bezeichner.

Und die Aufteilung in mehrere Zeilen würde ich Dir auch etwas ans Herz legen - das macht es auch einfacher lesbar.
 

Neue Themen


Oben