Nach TranslateAnimation blinkt animierte View kurz an falscher Stelle auf

  • Antworten:1
  • Bentwortet
Philip M.
  • Forum-Beiträge: 90

09.09.2011, 15:38:21 via Website

Guten Abend liebe Gemeinde,

da ich mich nun schon ein paar Wochen mit Android beschäftige und auch schon so einiges erreicht habe in meiner ersten App, bin ich jetzt wieder einmal an einer wahrscheinlich sehr einfachen Stelle am verzweifeln.

Ich habe mir ein Menu geschrieben, welches ein und ausfahren können soll. Das tut es auch wunderbar und macht in seiner Hauptfunktion keine Probleme. Das Problem ist nur, das wenn ich die Animation (Translate Animation) aufrufe, und die Animation einmal vollständig durchgelaufen ist, blinkt die View einmal beim einfahren kurz zu weit drüber und beim FadeOut einmal kurz zu weit unten auf.
Nach diesem "Blinken" sitzt das Menü aber an der richtigen Stelle.

Vielleicht könnt ihr mir ja bei diesem Problem helfen? Schön wäre es auf jedenfall, würde mich sher darüber freuen. :)
Poste hier drunter auch nochmal den Quellcode damit ihr es nachvollziehen könnt. Die Animation sitzt ganz unten in den beiden onClickListenern.

1public class ButtonMenuBottom extends LinearLayout {
2
3 private LinearLayout menuTop;
4 private LinearLayout menuMiddle;
5 private LinearLayout menuBottom;
6
7 private Button buttonFade;
8 private Button buttonHome;
9 private Button buttonProfil;
10 private Button buttonMehr;
11 private Button buttonHilfe;
12 private Button buttonInfo;
13
14 private float SCALE;
15
16 public ButtonMenuBottom(Context context, AttributeSet set) {
17 super(context, set);
18 LayoutInflater layoutInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
19 layoutInflater.inflate(R.layout.button_form_bottom, this);
20 SCALE = getResources().getDisplayMetrics().density;
21 initialize();
22 }
23
24 private void initialize() {
25 buttonHome = getButtonHome();
26 buttonHilfe = getButtonHilfe();
27 buttonInfo = getButtonInfo();
28 buttonMehr = getButtonMehr();
29 buttonProfil = getButtonProfil();
30 buttonFade = getButtonFade();
31 }
32
33 public Button getButtonHome() {
34 if(buttonHome == null) {
35 buttonHome = (Button)findViewById(R.id.buttonHome);
36 buttonHome.setOnClickListener(new OnClickListener() {
37 @Override
38 public void onClick(View v) {
39 getContext().startActivity(new Intent(getContext(), HomeActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
40 }
41 });
42 }
43 return buttonHome;
44 }
45
46 public Button getButtonProfil() {
47 if(buttonProfil == null) {
48 buttonProfil = (Button)findViewById(R.id.buttonProfil);
49 buttonProfil.setOnClickListener(new OnClickListener() {
50 @Override
51 public void onClick(View v) {
52 getContext().startActivity(new Intent(getContext(), ProfilActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
53 }
54 });
55 }
56 return buttonProfil;
57 }
58
59 public Button getButtonMehr() {
60 if(buttonMehr == null) {
61 buttonMehr = (Button)findViewById(R.id.buttonMehr);
62 buttonMehr.setOnClickListener(new OnClickListener() {
63 @Override
64 public void onClick(View v) {
65 getContext().startActivity(new Intent(getContext(), MehrActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
66 }
67 });
68 }
69 return buttonMehr;
70 }
71
72 public Button getButtonHilfe() {
73 if(buttonHilfe == null) {
74 buttonHilfe = (Button)findViewById(R.id.buttonHilfe);
75 buttonHilfe.setOnClickListener(new OnClickListener() {
76 @Override
77 public void onClick(View v) {
78 getContext().startActivity(new Intent(getContext(), HilfeActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
79 }
80 });
81 }
82 return buttonHilfe;
83 }
84
85 public Button getButtonInfo() {
86 if(buttonInfo == null) {
87 buttonInfo = (Button)findViewById(R.id.buttonInfo);
88 buttonInfo.setOnClickListener(new OnClickListener() {
89 @Override
90 public void onClick(View v) {
91 getContext().startActivity(new Intent(getContext(), InfoActivity.class).addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT).addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION));
92 }
93 });
94 }
95 return buttonInfo;
96 }
97
98 public Button getButtonFade() {
99 if(buttonFade == null) {
100 buttonFade = (Button)findViewById(R.id.buttonFade);
101 buttonFade.setOnClickListener(new SlideOutListener());
102 }
103 return buttonFade;
104 }
105
106 public LinearLayout getMenuTop() {
107 if(menuTop == null) {
108 menuTop = (LinearLayout)findViewById(R.id.menuTop);
109 }
110 return menuTop;
111 }
112
113 public LinearLayout getMenuMiddle() {
114 if(menuMiddle == null) {
115 menuMiddle = (LinearLayout)findViewById(R.id.menuMiddle);
116 }
117 return menuMiddle;
118 }
119
120 public LinearLayout getMenuBottom() {
121 if(menuBottom == null) {
122 menuBottom = (LinearLayout)findViewById(R.id.menuBottom);
123 }
124 return menuBottom;
125 }
126
127 private class SlideInListener implements OnClickListener {
128
129 @Override
130 public void onClick(View v) {
131// Damit ich nicht alles in Pixeln angebe, rechne ich hier die Pixel anhand des Bildschirmes passend um
132// SCALE wird oben definiert und kommt aus getResources().getDisplayMetrics().density;
133 final int dpi = (int) (75.0f * SCALE + 0.5f);
134 Animation animation = new TranslateAnimation(0, 0, 0, -dpi);
135 animation.setDuration(500);
136 animation.setAnimationListener(new AnimationListener() {
137 public void onAnimationStart(Animation animation) {}
138
139 public void onAnimationRepeat(Animation animation) {}
140
141 public void onAnimationEnd(Animation animation) {
142 ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
143 params.bottomMargin = 0;
144 setLayoutParams(params);
145 getButtonFade().setText(R.string.menuFadeOut);
146 getButtonFade().setOnClickListener(new SlideOutListener());
147 }
148 });
149 startAnimation(animation);
150 }
151 }
152
153 private class SlideOutListener implements OnClickListener {
154
155 @Override
156 public void onClick(View v) {
157// Damit ich nicht alles in Pixeln angebe, rechne ich hier die Pixel anhand des Bildschirmes passend um
158// SCALE wird oben definiert und kommt aus getResources().getDisplayMetrics().density;
159 final int dpi = (int) (75.0f * SCALE + 0.5f);
160 Animation animation = new TranslateAnimation(0, 0, 0, dpi);
161 animation.setDuration(500);
162 animation.setAnimationListener(new AnimationListener() {
163 public void onAnimationStart(Animation animation) {
164
165
166 }
167
168 public void onAnimationRepeat(Animation animation) {
169 // TODO Auto-generated method stub
170
171 }
172
173 public void onAnimationEnd(Animation animation) {
174 ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
175 params.bottomMargin = -dpi;
176 setLayoutParams(params);
177 getButtonFade().setText(R.string.menuFadeIn);
178 getButtonFade().setOnClickListener(new SlideInListener());
179 }
180 });
181 startAnimation(animation);
182 }
183 }
184}

Antworten
Philip M.
  • Forum-Beiträge: 90

12.09.2011, 09:20:36 via Website

Okay, nach ewiger Sucherei am Wochenende habe ich den Fehler endlich gefunden.
Das Problem war ein Bug mit dem AnimationListener, diesen kann man zZ zwar einer Animation anhängen, aber eben dann erhält man diesen Fehler welchen ich bisher auch hatte.
Um den Fehler nun zu umgehen muss man die onAnimationEnd() Methode der View, welche die Animation erhält überschreiben. Ist alles getestet un funktioniert nun einwandfrei, die überschriebene Methode sieht nun so aus:

1@Override
2 protected void onAnimationEnd() {
3 super.onAnimationEnd();
4 final int dpi = (int) (75.0f * SCALE + 0.5f);
5 ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)getLayoutParams();
6 if(menuPosition == MENU_POSITION.TOP) {
7 params.bottomMargin = 0;
8 setLayoutParams(params);
9 getButtonFade().setText(R.string.menuFadeOut);
10 getButtonFade().setOnClickListener(new SlideOutListener());
11
12 } else if(menuPosition == MENU_POSITION.DOWN) {
13 params.bottomMargin = -dpi;
14 setLayoutParams(params);
15 getButtonFade().setText(R.string.menuFadeIn);
16 getButtonFade().setOnClickListener(new SlideInListener());
17 }
18
19
20 }

Wobei menuPosition hier ein selbstgeschrieber ENUM ist um den zustand des Menüs zu erfahren (ist es ein- oder ausgeklappt).
Hoffe jemand anderem hier hilft die Lösung weiter. :)

//Edit:
Hier soll das Problem wohl auch nochmal gelistet sein:
http://code.google.com/p/android-misc-widgets/issues/detail?id=8

— geändert am 12.09.2011, 09:27:06

Ansgar M

Antworten