OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.appmenu; | 5 package org.chromium.chrome.browser.appmenu; |
6 | 6 |
7 import android.animation.Animator; | |
8 import android.animation.AnimatorListenerAdapter; | |
9 import android.animation.AnimatorSet; | |
10 import android.animation.ObjectAnimator; | |
7 import android.graphics.drawable.Drawable; | 11 import android.graphics.drawable.Drawable; |
8 import android.view.LayoutInflater; | 12 import android.view.LayoutInflater; |
9 import android.view.MenuItem; | 13 import android.view.MenuItem; |
10 import android.view.View; | 14 import android.view.View; |
11 import android.view.View.OnClickListener; | 15 import android.view.View.OnClickListener; |
12 import android.view.ViewGroup; | 16 import android.view.ViewGroup; |
17 import android.view.animation.DecelerateInterpolator; | |
13 import android.widget.BaseAdapter; | 18 import android.widget.BaseAdapter; |
14 import android.widget.ImageButton; | 19 import android.widget.ImageButton; |
20 import android.widget.ImageView; | |
15 import android.widget.ListView; | 21 import android.widget.ListView; |
16 import android.widget.TextView; | 22 import android.widget.TextView; |
17 | 23 |
18 import org.chromium.chrome.R; | 24 import org.chromium.chrome.R; |
19 | 25 |
20 import java.util.List; | 26 import java.util.List; |
21 | 27 |
22 /** | 28 /** |
23 * ListAdapter to customize the view of items in the list. | 29 * ListAdapter to customize the view of items in the list. |
24 */ | 30 */ |
(...skipping 11 matching lines...) Expand all Loading... | |
36 private static final int TITLE_BUTTON_MENU_ITEM = 1; | 42 private static final int TITLE_BUTTON_MENU_ITEM = 1; |
37 /** | 43 /** |
38 * Menu item that has three buttons. Every one of these buttons is displayed as an icon. | 44 * Menu item that has three buttons. Every one of these buttons is displayed as an icon. |
39 */ | 45 */ |
40 private static final int THREE_BUTTON_MENU_ITEM = 2; | 46 private static final int THREE_BUTTON_MENU_ITEM = 2; |
41 /** | 47 /** |
42 * Menu item that has four buttons. Every one of these buttons is displayed as an icon. | 48 * Menu item that has four buttons. Every one of these buttons is displayed as an icon. |
43 */ | 49 */ |
44 private static final int FOUR_BUTTON_MENU_ITEM = 3; | 50 private static final int FOUR_BUTTON_MENU_ITEM = 3; |
45 | 51 |
52 /** MenuItem Animation Constants */ | |
53 private static final int ENTER_ITEM_DURATION_MS = 500; | |
54 private static final int ENTER_ITEM_BASE_DELAY_MS = 100; | |
55 private static final int ENTER_ITEM_ADDL_DELAY_MS = 70; | |
56 private static final float ENTER_STANDARD_ITEM_OFFSET_Y_DP = -10.f; | |
57 private static final float ENTER_STANDARD_ITEM_OFFSET_X_DP = 10.f; | |
58 | |
46 private final AppMenu mAppMenu; | 59 private final AppMenu mAppMenu; |
47 private final LayoutInflater mInflater; | 60 private final LayoutInflater mInflater; |
48 private final List<MenuItem> mMenuItems; | 61 private final List<MenuItem> mMenuItems; |
49 private final int mNumMenuItems; | 62 private final int mNumMenuItems; |
63 private final float mDpToPx; | |
50 | 64 |
51 public AppMenuAdapter(AppMenu appMenu, List<MenuItem> menuItems, LayoutInfla ter inflater) { | 65 public AppMenuAdapter(AppMenu appMenu, List<MenuItem> menuItems, LayoutInfla ter inflater) { |
52 mAppMenu = appMenu; | 66 mAppMenu = appMenu; |
53 mMenuItems = menuItems; | 67 mMenuItems = menuItems; |
54 mInflater = inflater; | 68 mInflater = inflater; |
55 mNumMenuItems = menuItems.size(); | 69 mNumMenuItems = menuItems.size(); |
70 mDpToPx = inflater.getContext().getResources().getDisplayMetrics().densi ty; | |
56 } | 71 } |
57 | 72 |
58 @Override | 73 @Override |
59 public int getCount() { | 74 public int getCount() { |
60 return mNumMenuItems; | 75 return mNumMenuItems; |
61 } | 76 } |
62 | 77 |
63 @Override | 78 @Override |
64 public int getViewTypeCount() { | 79 public int getViewTypeCount() { |
65 return VIEW_TYPE_COUNT; | 80 return VIEW_TYPE_COUNT; |
(...skipping 30 matching lines...) Expand all Loading... | |
96 public View getView(int position, View convertView, ViewGroup parent) { | 111 public View getView(int position, View convertView, ViewGroup parent) { |
97 final MenuItem item = getItem(position); | 112 final MenuItem item = getItem(position); |
98 switch (getItemViewType(position)) { | 113 switch (getItemViewType(position)) { |
99 case STANDARD_MENU_ITEM: { | 114 case STANDARD_MENU_ITEM: { |
100 StandardMenuItemViewHolder holder = null; | 115 StandardMenuItemViewHolder holder = null; |
101 if (convertView == null) { | 116 if (convertView == null) { |
102 holder = new StandardMenuItemViewHolder(); | 117 holder = new StandardMenuItemViewHolder(); |
103 convertView = mInflater.inflate(R.layout.menu_item, parent, false); | 118 convertView = mInflater.inflate(R.layout.menu_item, parent, false); |
104 holder.text = (TextView) convertView.findViewById(R.id.menu_ item_text); | 119 holder.text = (TextView) convertView.findViewById(R.id.menu_ item_text); |
105 holder.image = (AppMenuItemIcon) convertView.findViewById(R. id.menu_item_icon); | 120 holder.image = (AppMenuItemIcon) convertView.findViewById(R. id.menu_item_icon); |
106 convertView.setTag(holder); | 121 convertView.setTag(holder); |
aurimas (slooooooooow)
2014/07/15 01:37:25
Should we set a key for this tag? I am not sure ho
David Trainor- moved to gerrit
2014/07/15 20:53:38
We don't need one. getTag()/setTag(Object) store
aurimas (slooooooooow)
2014/07/16 17:03:42
Acknowledged.
| |
122 convertView.setTag(R.id.menu_item_enter_anim_id, | |
123 buildStandardItemEnterAnimator(convertView, position )); | |
124 convertView.setTag(R.id.menu_item_exit_anim_id, | |
125 buildItemExitAnimator(convertView)); | |
107 } else { | 126 } else { |
108 holder = (StandardMenuItemViewHolder) convertView.getTag(); | 127 holder = (StandardMenuItemViewHolder) convertView.getTag(); |
109 } | 128 } |
110 | 129 |
111 convertView.setOnClickListener(new OnClickListener() { | 130 convertView.setOnClickListener(new OnClickListener() { |
112 @Override | 131 @Override |
113 public void onClick(View v) { | 132 public void onClick(View v) { |
114 mAppMenu.onItemClick(item); | 133 mAppMenu.onItemClick(item); |
115 } | 134 } |
116 }); | 135 }); |
117 // Set up the icon. | 136 // Set up the icon. |
118 Drawable icon = item.getIcon(); | 137 Drawable icon = item.getIcon(); |
119 holder.image.setImageDrawable(icon); | 138 holder.image.setImageDrawable(icon); |
120 holder.image.setVisibility(icon == null ? View.GONE : View.VISIB LE); | 139 holder.image.setVisibility(icon == null ? View.GONE : View.VISIB LE); |
121 holder.image.setChecked(item.isChecked()); | 140 holder.image.setChecked(item.isChecked()); |
122 | 141 |
123 holder.text.setText(item.getTitle()); | 142 holder.text.setText(item.getTitle()); |
124 boolean isEnabled = item.isEnabled(); | 143 boolean isEnabled = item.isEnabled(); |
125 // Set the text color (using a color state list). | 144 // Set the text color (using a color state list). |
126 holder.text.setEnabled(isEnabled); | 145 holder.text.setEnabled(isEnabled); |
127 // This will ensure that the item is not highlighted when select ed. | 146 // This will ensure that the item is not highlighted when select ed. |
128 convertView.setEnabled(isEnabled); | 147 convertView.setEnabled(isEnabled); |
129 break; | 148 break; |
130 } | 149 } |
131 case THREE_BUTTON_MENU_ITEM: { | 150 case THREE_BUTTON_MENU_ITEM: { |
132 ThreeButtonMenuItemViewHolder holder = null; | 151 ThreeButtonMenuItemViewHolder holder = null; |
133 if (convertView == null) { | 152 if (convertView == null) { |
134 holder = new ThreeButtonMenuItemViewHolder(); | 153 holder = new ThreeButtonMenuItemViewHolder(); |
135 convertView = mInflater.inflate(R.layout.three_button_menu_i tem, parent, false); | 154 convertView = mInflater.inflate(R.layout.three_button_menu_i tem, parent, false); |
136 holder.buttonOne = (ImageButton) convertView.findViewById(R. id.button_one); | 155 holder.buttons[0] = (ImageButton) convertView.findViewById(R .id.button_one); |
137 holder.buttonTwo = (ImageButton) convertView.findViewById(R. id.button_two); | 156 holder.buttons[1] = (ImageButton) convertView.findViewById(R .id.button_two); |
138 holder.buttonThree = (ImageButton) convertView.findViewById( R.id.button_three); | 157 holder.buttons[2] = (ImageButton) convertView.findViewById(R .id.button_three); |
139 convertView.setTag(holder); | 158 convertView.setTag(holder); |
159 convertView.setTag(R.id.menu_item_enter_anim_id, | |
160 buildIconItemEnterAnimator(holder.buttons, false)); | |
161 convertView.setTag(R.id.menu_item_exit_anim_id, | |
162 buildItemExitAnimator(convertView)); | |
140 } else { | 163 } else { |
141 holder = (ThreeButtonMenuItemViewHolder) convertView.getTag( ); | 164 holder = (ThreeButtonMenuItemViewHolder) convertView.getTag( ); |
142 } | 165 } |
143 setupImageButton(holder.buttonOne, item.getSubMenu().getItem(0)) ; | 166 setupImageButton(holder.buttons[0], item.getSubMenu().getItem(0) ); |
144 setupImageButton(holder.buttonTwo, item.getSubMenu().getItem(1)) ; | 167 setupImageButton(holder.buttons[1], item.getSubMenu().getItem(1) ); |
145 setupImageButton(holder.buttonThree, item.getSubMenu().getItem(2 )); | 168 setupImageButton(holder.buttons[2], item.getSubMenu().getItem(2) ); |
146 convertView.setFocusable(false); | 169 convertView.setFocusable(false); |
147 convertView.setEnabled(false); | 170 convertView.setEnabled(false); |
148 break; | 171 break; |
149 } | 172 } |
150 case FOUR_BUTTON_MENU_ITEM: { | 173 case FOUR_BUTTON_MENU_ITEM: { |
151 FourButtonMenuItemViewHolder holder = null; | 174 FourButtonMenuItemViewHolder holder = null; |
152 if (convertView == null) { | 175 if (convertView == null) { |
153 holder = new FourButtonMenuItemViewHolder(); | 176 holder = new FourButtonMenuItemViewHolder(); |
154 convertView = mInflater.inflate(R.layout.four_button_menu_it em, parent, false); | 177 convertView = mInflater.inflate(R.layout.four_button_menu_it em, parent, false); |
155 holder.buttonOne = (ImageButton) convertView.findViewById(R. id.button_one); | 178 holder.buttons[0] = (ImageButton) convertView.findViewById(R .id.button_one); |
156 holder.buttonTwo = (ImageButton) convertView.findViewById(R. id.button_two); | 179 holder.buttons[1] = (ImageButton) convertView.findViewById(R .id.button_two); |
157 holder.buttonThree = (ImageButton) convertView.findViewById( R.id.button_three); | 180 holder.buttons[2] = (ImageButton) convertView.findViewById(R .id.button_three); |
158 holder.buttonFour = (ImageButton) convertView.findViewById(R .id.button_four); | 181 holder.buttons[3] = (ImageButton) convertView.findViewById(R .id.button_four); |
159 convertView.setTag(holder); | 182 convertView.setTag(holder); |
183 convertView.setTag(R.id.menu_item_enter_anim_id, | |
184 buildIconItemEnterAnimator(holder.buttons, false)); | |
185 convertView.setTag(R.id.menu_item_exit_anim_id, | |
186 buildItemExitAnimator(convertView)); | |
160 } else { | 187 } else { |
161 holder = (FourButtonMenuItemViewHolder) convertView.getTag() ; | 188 holder = (FourButtonMenuItemViewHolder) convertView.getTag() ; |
162 } | 189 } |
163 setupImageButton(holder.buttonOne, item.getSubMenu().getItem(0)) ; | 190 setupImageButton(holder.buttons[0], item.getSubMenu().getItem(0) ); |
164 setupImageButton(holder.buttonTwo, item.getSubMenu().getItem(1)) ; | 191 setupImageButton(holder.buttons[1], item.getSubMenu().getItem(1) ); |
165 setupImageButton(holder.buttonThree, item.getSubMenu().getItem(2 )); | 192 setupImageButton(holder.buttons[2], item.getSubMenu().getItem(2) ); |
166 setupImageButton(holder.buttonFour, item.getSubMenu().getItem(3) ); | 193 setupImageButton(holder.buttons[3], item.getSubMenu().getItem(3) ); |
167 convertView.setFocusable(false); | 194 convertView.setFocusable(false); |
168 convertView.setEnabled(false); | 195 convertView.setEnabled(false); |
169 break; | 196 break; |
170 } | 197 } |
171 case TITLE_BUTTON_MENU_ITEM: { | 198 case TITLE_BUTTON_MENU_ITEM: { |
172 TitleButtonMenuItemViewHolder holder = null; | 199 TitleButtonMenuItemViewHolder holder = null; |
173 if (convertView == null) { | 200 if (convertView == null) { |
174 holder = new TitleButtonMenuItemViewHolder(); | 201 holder = new TitleButtonMenuItemViewHolder(); |
175 convertView = mInflater.inflate(R.layout.title_button_menu_i tem, parent, false); | 202 convertView = mInflater.inflate(R.layout.title_button_menu_i tem, parent, false); |
176 holder.title = (TextView) convertView.findViewById(R.id.titl e); | 203 holder.title = (TextView) convertView.findViewById(R.id.titl e); |
177 holder.button = (ImageButton) convertView.findViewById(R.id. button); | 204 holder.button = (ImageButton) convertView.findViewById(R.id. button); |
178 convertView.setTag(holder); | 205 convertView.setTag(holder); |
206 convertView.setTag(R.id.menu_item_enter_anim_id, | |
207 buildStandardItemEnterAnimator(convertView, position )); | |
208 convertView.setTag(R.id.menu_item_exit_anim_id, | |
209 buildItemExitAnimator(convertView)); | |
179 } else { | 210 } else { |
180 holder = (TitleButtonMenuItemViewHolder) convertView.getTag( ); | 211 holder = (TitleButtonMenuItemViewHolder) convertView.getTag( ); |
181 } | 212 } |
182 final MenuItem titleItem = item.getSubMenu().getItem(0); | 213 final MenuItem titleItem = item.getSubMenu().getItem(0); |
183 holder.title.setText(titleItem.getTitle()); | 214 holder.title.setText(titleItem.getTitle()); |
184 holder.title.setEnabled(titleItem.isEnabled()); | 215 holder.title.setEnabled(titleItem.isEnabled()); |
185 holder.title.setFocusable(titleItem.isEnabled()); | 216 holder.title.setFocusable(titleItem.isEnabled()); |
186 holder.title.setOnClickListener(new OnClickListener() { | 217 holder.title.setOnClickListener(new OnClickListener() { |
187 @Override | 218 @Override |
188 public void onClick(View v) { | 219 public void onClick(View v) { |
(...skipping 26 matching lines...) Expand all Loading... | |
215 button.setEnabled(item.isEnabled()); | 246 button.setEnabled(item.isEnabled()); |
216 button.setFocusable(item.isEnabled()); | 247 button.setFocusable(item.isEnabled()); |
217 button.setOnClickListener(new OnClickListener() { | 248 button.setOnClickListener(new OnClickListener() { |
218 @Override | 249 @Override |
219 public void onClick(View v) { | 250 public void onClick(View v) { |
220 mAppMenu.onItemClick(item); | 251 mAppMenu.onItemClick(item); |
221 } | 252 } |
222 }); | 253 }); |
223 } | 254 } |
224 | 255 |
256 private Animator buildStandardItemEnterAnimator(final View view, int positio n) { | |
aurimas (slooooooooow)
2014/07/15 01:37:26
Please add some comments to these animator constru
David Trainor- moved to gerrit
2014/07/15 20:53:38
Will do.
| |
257 final float offsetYPx = ENTER_STANDARD_ITEM_OFFSET_Y_DP * mDpToPx; | |
258 final int startDelay = ENTER_ITEM_BASE_DELAY_MS + ENTER_ITEM_ADDL_DELAY_ MS * position; | |
259 | |
260 AnimatorSet animation = new AnimatorSet(); | |
261 animation.playTogether( | |
262 ObjectAnimator.ofFloat(view, View.ALPHA, 0.f, 1.f), | |
263 ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, offsetYPx, 0.f) ); | |
264 animation.setDuration(ENTER_ITEM_DURATION_MS); | |
265 animation.setStartDelay(startDelay); | |
266 // TODO(dtrainor): Update to material interpolators. | |
267 animation.setInterpolator(new DecelerateInterpolator()); | |
268 | |
269 animation.addListener(new AnimatorListenerAdapter() { | |
270 @Override | |
271 public void onAnimationStart(Animator animation) { | |
272 view.setAlpha(0.f); | |
273 } | |
274 }); | |
275 return animation; | |
276 } | |
277 | |
278 private Animator buildIconItemEnterAnimator(final ImageView[] views, boolean skipLastItem) { | |
279 final float offsetXPx = ENTER_STANDARD_ITEM_OFFSET_X_DP * mDpToPx; | |
280 final int maxViewsToAnimate = views.length - (skipLastItem ? 1 : 0); | |
281 | |
282 AnimatorSet animation = new AnimatorSet(); | |
283 AnimatorSet.Builder builder = null; | |
284 for (int i = 0; i < maxViewsToAnimate; i++) { | |
285 final int startDelay = ENTER_ITEM_ADDL_DELAY_MS * i; | |
286 | |
287 Animator alpha = ObjectAnimator.ofFloat(views[i], View.ALPHA, 0.f, 1 .f); | |
288 Animator translate = ObjectAnimator.ofFloat(views[i], View.TRANSLATI ON_X, offsetXPx, 0); | |
289 alpha.setStartDelay(startDelay); | |
290 translate.setStartDelay(startDelay); | |
291 alpha.setDuration(ENTER_ITEM_DURATION_MS); | |
292 translate.setDuration(ENTER_ITEM_DURATION_MS); | |
293 | |
294 if (builder == null) { | |
295 builder = animation.play(alpha); | |
296 } else { | |
297 builder.with(alpha); | |
298 } | |
299 builder.with(translate); | |
300 } | |
301 animation.setStartDelay(ENTER_ITEM_BASE_DELAY_MS); | |
302 // TODO(dtrainor): Update to material interpolators. | |
303 animation.setInterpolator(new DecelerateInterpolator()); | |
304 | |
305 animation.addListener(new AnimatorListenerAdapter() { | |
306 @Override | |
307 public void onAnimationStart(Animator animation) { | |
308 for (int i = 0; i < maxViewsToAnimate; i++) { | |
309 views[i].setAlpha(0.f); | |
310 } | |
311 } | |
312 }); | |
313 return animation; | |
314 } | |
315 | |
316 private Animator buildItemExitAnimator(View view) { | |
317 return ObjectAnimator.ofFloat(view, View.ALPHA, 1.f, 0.f).setDuration(0) ; | |
aurimas (slooooooooow)
2014/07/15 01:37:26
What does it mean to have an animation of length 0
David Trainor- moved to gerrit
2014/07/15 20:53:38
It means right now they just hide immediately. Bu
aurimas (slooooooooow)
2014/07/16 17:03:42
Acknowledged.
| |
318 } | |
319 | |
225 static class StandardMenuItemViewHolder { | 320 static class StandardMenuItemViewHolder { |
226 public TextView text; | 321 public TextView text; |
227 public AppMenuItemIcon image; | 322 public AppMenuItemIcon image; |
228 } | 323 } |
229 | 324 |
230 static class ThreeButtonMenuItemViewHolder { | 325 static class ThreeButtonMenuItemViewHolder { |
231 public ImageButton buttonOne; | 326 public ImageButton[] buttons = new ImageButton[3]; |
232 public ImageButton buttonTwo; | |
233 public ImageButton buttonThree; | |
234 } | 327 } |
235 | 328 |
236 static class FourButtonMenuItemViewHolder { | 329 static class FourButtonMenuItemViewHolder { |
237 public ImageButton buttonOne; | 330 public ImageButton[] buttons = new ImageButton[4]; |
238 public ImageButton buttonTwo; | |
239 public ImageButton buttonThree; | |
240 public ImageButton buttonFour; | |
241 } | 331 } |
242 | 332 |
243 static class TitleButtonMenuItemViewHolder { | 333 static class TitleButtonMenuItemViewHolder { |
244 public TextView title; | 334 public TextView title; |
245 public ImageButton button; | 335 public ImageButton button; |
246 } | 336 } |
247 } | 337 } |
OLD | NEW |