1. Mitglieder surfen ohne Werbung auf Android-Hilfe.de! ✔ Jetzt kostenlos Mitglied in unserer Community werden.
  1. no1Ltan, 08.10.2018 #1
    no1Ltan

    no1Ltan Threadstarter Erfahrener Benutzer

    Hi Leute,

    ich würde gerne folgendes realisieren:
    Bei einem Klick auf einen Button, der sich innerhalb eines ConstraintLayouts befindet,
    soll dessen Position verschoben werden.
    Um es wie eine Art Effekt aussehen zu lassen, soll die Position mehrmals verschoben werden.

    Ich habe es so, wie in dem Code unten, probiert.
    Es gibt allerdings gleich 2 Probleme/Unklarheiten:

    Problem 1)
    Der Delay funktioniert anscheinend nur 1x.
    Beim Klick auf den Button wird dessen Position nach 500 ms verschoben.
    Danach passiert nichts mehr.
    Ich hatte eigentlich erwartet, dass zwischen den einzelnen for-loops je 500 ms Pause sind.
    Die Log zeigt mir, dass die for-Schleife 10x durchgelaufen ist - allerdings nur mit 1x 500 ms Pause.

    Natürlich hatte ich statt x++ auch x = x + 20 probiert, um die Unterschiede deutlich sichtbar zu machen.

    Problem 2)
    Ich habe die x-Variable im Programmkopf mit dem Wert 200 initialisiert.
    In meinem Beispiel hier funktioniert es zwar, aber in Echt müsste der tatsächliche Wert,
    der sich innerhalb der lp-Variable befindet, incrementiert werden.
    Wie soll das aber gehen?
    In der lp müssten sich ja 4 Werte befinden: Left, Top, Right, Bottom.
    Heißt also, statt x++ müsste ich eher mit "top++" arbeiten, was so nicht funktionieren würde.
    Code:
    for (int i = 1; i <= 10; i++) // 10 loops
            {
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable()
                {
                    @Override
                    public void run()
                    {
                        x++; // Increment x by 1
                        ConstraintLayout.LayoutParams lp = (ConstraintLayout.LayoutParams) button1.getLayoutParams(); // Get current margins of button 1
                        lp.setMargins(0, x, 0, 0); // Write margin values inside of lp variable (L, T, R, B)
                        button1.setLayoutParams(lp); // Change margin of button1
                        Log.wtf("x ist:", String.valueOf(x)); // Show current value of x in Log - LOG IS OK!
                    }
                }, 500); // 500 ms delay
    
    Danke für jede Hilfe!
     
  2. deek, 08.10.2018 #2
    deek

    deek Android-Experte

    Punkt 1:
    Deine for Schleife läuft ja quasi sofort durch. Das heißt du erzeugst 10 runnables, die nach 500ms getriggert werden. Also werden 500ms nach dem ersten SChleifendurchlauf alle 10 runnables (+der Zeit, die ein Schleifendurchlauf dauert, aber das ist marginal) gestartet, damit geht das so schnell, dass du nur den letzten positionswechsel siehst.
    Möchtest du das so machen musst du entweder deine 500 ms mit i malnehmen beim posten oder in den runnalbe selbst am Ende ein neues Runnable posten.

    Punkt 2:
    So sollte man das nicht machen, dafür kann man einen ObjectAnimator nehmen:
    Move a View with Animation  |  Android Developers
     
    no1Ltan bedankt sich.
  3. no1Ltan, 08.10.2018 #3
    no1Ltan

    no1Ltan Threadstarter Erfahrener Benutzer

    Hallo deek,

    Punkt 1:
    Muss ich mir genauer anschauen.
    Das, was du schreibst, ergibt für mich auf jeden Fall schon mal Sinn.

    Punkt 2:
    Super, dann brauche ich das Rad ja nicht neu erfinden :)
    Habe es jetzt so hier gemacht, und es entspricht in der Tat meinen Vorstellungen!

    Code:
         oa = ObjectAnimator.ofFloat(button1, "translationX", 30f, 0f); // Move object 30px to right, then back to 0
         oa.setDuration(100); // 100 ms animation duration
         oa.setRepeatCount(3); // Repeat animation 3 times
         oa.start(); // Start animation!
    
    Soweit ich es verstanden habe arbeitet der ObjectAnimator relativ, also heißt 0f Ausgangsposition,
    nicht Absolutwert: 0 Pixel.
    30f, 0f -> Verschiebe Object AB HIER um 30px nach rechts, dann wieder zurück auf die Ursprungsposition.

    P.S. Im Programmkopf hab ich natürlich den ObjectAnimator (oa) deklariert.

    Vielen Dank!
    -- Dieser Beitrag wurde automatisch mit dem folgenden Beitrag zusammengeführt --
    Hallo,

    ich muss leider nochmal was fragen.

    Bei mehreren Buttons habe ich es jetzt so gemacht, dass alle Buttons eine Methode aufrufen,
    die für die Animation zuständig ist und "sich selbst schicken".
    (Ist sicherlich die bessere Variante statt den Codeblock x mal zu kopieren und einzufügen.)

    Das hier funktioniert einwandfrei:
    Code:
    .
    .
    .
    ObjectAnimator oa; // Access variable for ObjectAnimator
    .
    .
    .
            button1.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    animationEffect(button1); // Run animation method for this button
                }
            });
            button2.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    animationEffect(button2); // Run animation method for this button
                }
            });
    .
    .
    .
        public void animationEffect(Button o) // Animation effect for selected object
        {
            oa = ObjectAnimator.ofFloat(o, "translationX", 30f, 0f); // Move object 30px to right, then back to 0
            oa.setDuration(100); // 100 ms animation duration
            oa.setRepeatCount(1); // Repeat animation 3 times
            oa.start(); // Start animation!
        }
    
    Das Problem ist jedoch, dass ich das nur für Buttons nutzen kann.
    Wenn ich z.B. bei einer klickbaren TextView den Effekt hinzufügen will, wird es nicht gehen.
    Code:
            textViewBlue.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    animationEffect(textViewBlue); // Hier erwartet die Methode einen Button
                }
            });
    
    Bei animationEffect((Button)textViewBlue); verschwindet zwar die Warnung, aber die App stürzt ab, sobald ich auf die tv klicke.

    Muss ich für jeden klickbaren Objekttypen eine separate Methode erzeugen, oder kann ich statt:
    Button o
    auch einfach sowas wie:
    Object o
    machen?
    (Object o hat nicht funktioniert)

    P.S. Butterknife habe ich nicht vergessen, es steht noch auf meiner ToDo-Liste ;)
     
  4. deek, 08.10.2018 #4
    deek

    deek Android-Experte

    animationEffect(View view) sollte gehen.
    Du kannst hatl eine TextView nicht zu einem Button casten. Aber ein Object ist zu allgemeint für ObjectAnimator nehme ich an.
     
    no1Ltan bedankt sich.
  5. no1Ltan, 09.10.2018 #5
    no1Ltan

    no1Ltan Threadstarter Erfahrener Benutzer

    Hat geklappt - Super.
    Danke nochmals!
     
Die Seite wird geladen...
Ähnliche Themen Forum Datum
Problem mit variable.setText (für TextView) Android App Entwicklung 25.10.2018
MIT AppInventor App erstellen um PDFs zu öffnen, problem Android App Entwicklung 10.10.2018
Problem mit startActivityForResult() Android App Entwicklung 25.01.2018
Du betrachtest das Thema "Problem mit for-Schleife, delay und Margins" im Forum "Android App Entwicklung",
  1. Android-Hilfe.de verwendet Cookies um Inhalte zu personalisieren und dir den bestmöglichen Service zu gewährleisten. Wenn du auf der Seite weitersurfst stimmst du der Cookie-Nutzung zu.  Ich stimme zu.