Objekt springt bei nächster Animation zurück

  • Antworten:4
Olli S
  • Forum-Beiträge: 8

11.03.2014, 13:48:07 via Website

Hallo,
ich sitze an einem komischen Problem in Bezug auf Animationen, für das ich leider seit langem keine Lösung finde.
Ich animiere ImageViews mittels Animationen, genauer gesagt mit Verwendung von ObjectAnimator und AnimatorSets.
Die Auslösung der Animation erfolgt in einem eigenen Thread (per Benutzereingabe), mittels runOnUIThread() wird die Animation dann ausgeführt.
Eine Animation funktioniert nun problemlos, doch sobald die nächste Animation gestartet wird, springt das ImageView wieder an die originale Position zurück.
Ich weiß, bei Verwendung der Animation Klasse muss setFilAfter o.ä. gesetzt werden, dieses ist meines Wissens bei Verwendung des ObjectAnimators nicht nötig und möglich. Im Debugmodus sehe ich auch die korrekte Position des Steuerelements nach Beendigung der Animation, lediglich bei Start der neuen Animation springt es zurück.
Hat jemand eine Vermutung wieso dieses komische Verhalten zustande kommt?

Vielen Dank im Voraus
Oliver

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

11.03.2014, 13:50:41 via Website

Wärst du so nett und zeigst und deinen Code, damit wir eine genaue Aussage darüber machen können. :)

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Olli S
  • Forum-Beiträge: 8

11.03.2014, 14:49:26 via Website

Danke schonmal für deine schnelle Antwort!
Hmm ich versuche mal ein funktionierendes Minimalbeispiel zu erstellen, denn leider ist der Code sehr lang ...

Antworten
Olli S
  • Forum-Beiträge: 8

11.03.2014, 14:57:12 via Website

Etwa so:

Aufruf der ersten Animation im Nebenhread:

1while (true) {
2 ArrayList<ImageView> ToBeMarked = new ArrayList<ImageView> ();
3 ToBeMarked.add (Map.GetPos (i - 1).Img); // Map.GetPos gibt das jeweilige ImageView zurück
4 ToBeMarked.add (Map.GetPos (i).Img);
5 Show.Mark (ToBeMarked);
6 _step = false;
7 while (!_step)
8 Thread.sleep(500);
9
10
11 if (Map.GetPos (i - 1).Nr > Map.GetPos (i).Nr) { // im ersten Durchlauf springen wir hierrein
12 Map.SwapPos (i - 1, i);
13 Show.Swap (Map.GetPos (i).Img, Map.GetPos (i - 1).Img); // Show ist andere Activity, dazu unten
14 } else { // im 2. dann hier
15 ArrayList<ImageView> ToBeUnMarked = new ArrayList<ImageView> ();
16 ToBeUnMarked.add (Map.GetPos (i - 1).Img);
17 ToBeUnMarked.add (Map.GetPos (i).Img);
18 Show.UnMark (ToBeUnMarked);
19 }
20
21 _step = false;
22 while (!_step)
23 Thread.sleep(500);
24
25 }

Nun zur Activty Show, hier wird per Buttonclick _step gesetzt, sodass obiger Thread weiterläuft:

1public void Mark(final ArrayList<ImageView> targets) {
2
3 runOnUiThread(new Runnable() {
4
5 @Override
6 public void run() {
7 AnimatorSet AS = new AnimatorSet ();
8
9 ArrayList<Animator> Animations = new ArrayList<Animator> ();
10 for (ImageView img : targets) {
11 Animations.add (AnimLowerMark (img));
12 }
13
14 AS.playTogether (Animations);
15 AS.start ();
16
17 }
18 });
19
20 }
21
22public void UnMark(final ArrayList<ImageView> targets) {
23
24 runOnUiThread(new Runnable() {
25
26 @Override
27 public void run() {
28 AnimatorSet AS = new AnimatorSet ();
29
30 ArrayList<Animator> Animations = new ArrayList<Animator> ();
31 for (ImageView img : targets) {
32 if (img.getTop() != MinTop)
33 Animations.add (AnimRaiseMark (img));
34 }
35
36 AS.playTogether (Animations);
37 AS.start ();
38
39 }
40 });
41
42 }
43
44public void Swap(final ImageView target1, final ImageView target2)
45 {
46
47 runOnUiThread(new Runnable() {
48
49 @Override
50 public void run() {
51 ObjectAnimator LowerOne = AnimLower (target1, 1);
52 ObjectAnimator LowerTwo = AnimLower (target2, 2);
53
54 ObjectAnimator Right = ObjectAnimator.ofInt (target1, "Left", target1.getLeft(), target2.getLeft() - 1);
55 Right.setDuration (Speed * 500);
56 ObjectAnimator Left = ObjectAnimator.ofInt (target2, "Left", target2.getLeft(), target1.getLeft());
57 Left.setDuration (Speed * 500);
58
59 ObjectAnimator RaiseOne = AnimRaise (target1, 1, 0);
60 ObjectAnimator RaiseTwo = AnimRaise (target2, 2, 0);
61
62 ObjectAnimator Correct = ObjectAnimator.ofInt (target1, "Left", target2.getLeft(), target2.getLeft() + 1);
63 Correct.setDuration (Speed * 500); // here was right if wrong
64
65 AnimatorSet Lower = new AnimatorSet ();
66 Lower.play (LowerOne).with (LowerTwo);
67
68 AnimatorSet Switch = new AnimatorSet ();
69 Switch.play (Right).with (Left);
70
71 AnimatorSet CorrectRaise = new AnimatorSet ();
72 CorrectRaise.play (RaiseOne).with (Correct);
73
74 AnimatorSet Raise = new AnimatorSet ();
75 Raise.play (CorrectRaise).with (RaiseTwo);
76
77 AnimatorSet LowerSwitch = new AnimatorSet ();
78 LowerSwitch.play (Lower).before (Switch);
79 AnimatorSet Complete = new AnimatorSet ();
80 Complete.play (LowerSwitch).before (Raise);
81
82 Complete.start ();
83
84 }
85 });
86
87
88 }
89
90private ObjectAnimator AnimLower(ImageView target, int factor)
91 {
92 ObjectAnimator ObjA = ObjectAnimator.ofInt (target, "Top", target.getTop(), (int)(Size * factor));
93 ObjA.setDuration (Speed * 500);
94 return ObjA;
95 }
96
97 private ObjectAnimator AnimLowerMark(ImageView target)
98 {
99 ObjectAnimator ObjA = ObjectAnimator.ofInt (target, "Top", target.getTop(), (int)(Size / 3));
100 ObjA.setDuration (Speed * 500);
101 return ObjA;
102 }
103
104 private ObjectAnimator AnimRaiseMark(ImageView target)
105 {
106 ObjectAnimator ObjA = ObjectAnimator.ofInt (target, "Top", (int)(Size / 3), MinTop);
107 ObjA.setDuration (Speed * 500);
108 return ObjA;
109 }
110
111 private ObjectAnimator AnimRaise(ImageView target, int start, int end)
112 {
113 ObjectAnimator ObjA = ObjectAnimator.ofInt (target, "Top", (int)(Size * start), MinTop + (int)(Size * end));
114 ObjA.setDuration (Speed * 500);
115 return ObjA;
116 }

Äh, okay so? :)

Antworten
Olli S
  • Forum-Beiträge: 8

16.03.2014, 22:47:41 via Website

Kein Rat? :(
Ist der Code noch zu unverständlich / aus dem Kontext gerissen?

Antworten