Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(43)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/widget/ContextMenuDialog.java

Issue 2868403003: added scale animation for context menu (Closed)
Patch Set: comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.chrome.browser.widget;
6
7 import android.app.Activity;
8 import android.graphics.Rect;
9 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
10 import android.view.MotionEvent;
11 import android.view.View;
12 import android.view.View.OnLayoutChangeListener;
13 import android.view.ViewGroup;
14 import android.view.Window;
15 import android.view.animation.Animation;
16 import android.view.animation.Animation.AnimationListener;
17 import android.view.animation.ScaleAnimation;
18
19 import org.chromium.content.browser.RenderCoordinates;
20
21 /**
22 * ContextMenuDialog is a subclass of AlwaysDismissedDialog that ensures that th e proper scale
23 * animation is played upon calling dismiss().
24 */
25 public class ContextMenuDialog extends AlwaysDismissedDialog {
26 private static final int ENTER_ANIMATION_DURATION = 250;
27 // Exit animation duration should be set to 60% of the enter animation durat ion.
28 private static final int EXIT_ANIMATION_DURATION = 150;
29
30 private View mContentView;
31 private float mContextMenuSourceX;
32 private float mContextMenuSourceY;
33 private int mContextMenuFirstLocationY;
34
35 public ContextMenuDialog(Activity ownerActivity, int theme) {
36 super(ownerActivity, theme);
37 }
38
39 /**
40 * @param contentView The content view to run the animation on.
41 * @param touchPointX The x-coordinate of the touch that triggered the conte xt menu in pixels.
42 * @param touchPointY The y-coordinate of the touch that triggered the conte xt menu in pixels.
43 * @param activity Activity to determine the number of pixels to the left an d above of the
44 * window.
45 * @param renderCoordinates Render coordinates to determine the y offset tak en by non content
46 * window items.
47 */
48 public void setupEnterAnimationAndShow(final View contentView, final float t ouchPointX,
Theresa 2017/05/24 22:50:50 How about an init() methods that takes all of thes
Daniel Park 2017/05/25 17:12:36 Done.
49 final float touchPointY, final Activity activity,
50 final RenderCoordinates renderCoordinates) {
51 mContentView = contentView;
52 mContentView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
53
54 @Override
55 public void onLayoutChange(View v, int left, int top, int right, int bottom,
56 int oldLeft, int oldTop, int oldRight, int oldBottom) {
57 ViewGroup group = (ViewGroup) v;
58 for (int i = 0; i < group.getChildCount(); i++) {
59 if (group.getChildAt(i).getHeight() == 0
60 && group.getChildAt(i).getVisibility() == View.VISIB LE) {
61 // Return early because not all the views have been meas ured, so animation
62 // pivots will be off.
63 return;
64 }
65 }
66 mContentView.setVisibility(View.VISIBLE);
67 startEnterAnimation(touchPointX, touchPointY, activity, renderCo ordinates);
68 mContentView.removeOnLayoutChangeListener(this);
69 }
70 });
71 super.show();
72 }
73
74 /**
75 * @param touchPointX The x-coordinate of the touch that triggered the conte xt menu in pixels.
76 * @param touchPointY The y-coordinate of the touch that triggered the conte xt menu in pixels.
77 * @param activity Activity to determine the number of pixels to the left an d above of the
78 * window.
79 * @param renderCoordinates Render coordinates to determine the y offset tak en by non content
80 * window items.
81 */
82 private void startEnterAnimation(float touchPointX, float touchPointY, Activ ity activity,
83 RenderCoordinates renderCoordinates) {
84 int[] currentLocationOnScreen = new int[2];
85 mContentView.getLocationOnScreen(currentLocationOnScreen);
86
87 mContextMenuFirstLocationY = currentLocationOnScreen[1];
88 Animation animation = getStartAnimation(
89 touchPointX, touchPointY, currentLocationOnScreen, activity, ren derCoordinates);
90 mContentView.startAnimation(animation);
91 }
92
93 /**
94 * @param touchPointX The x-coordinate of the touch that triggered the conte xt menu in pixels.
95 * @param touchPointY The y-coordinate of the touch that triggered the conte xt menu in pixels.
96 * @param currentLocationOnScreen A 2-element array that stores the x,y coor dinates of the view
97 * in its 0th and 1st indices respectively.
98 * @param activity Activity to determine the number of pixels to the left an d above of the
99 * window.
100 * @param renderCoordinates Render coordinates to determine the y offset tak en by non content
101 * window items.
102 */
103 private Animation getStartAnimation(float touchPointX, float touchPointY,
Theresa 2017/05/24 22:50:50 I would combine this with startEnterAnimation(). T
Daniel Park 2017/05/25 17:12:37 Done.
104 int[] currentLocationOnScreen, Activity activity, RenderCoordinates renderCoordinates) {
105 Rect rectangle = new Rect();
106 Window window = activity.getWindow();
107 window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
108
109 float xOffset = rectangle.left;
110 float yOffset = rectangle.top + renderCoordinates.getContentOffsetYPix() ;
111
112 mContextMenuSourceX = touchPointX - currentLocationOnScreen[0] + xOffset ;
113 mContextMenuSourceY = touchPointY - currentLocationOnScreen[1] + yOffset ;
114
115 return getScaleAnimation(true, mContextMenuSourceX, mContextMenuSourceY) ;
116 }
117
118 @Override
119 public void dismiss() {
120 int[] contextMenuFinalLocation = new int[2];
121 mContentView.getLocationOnScreen(contextMenuFinalLocation);
122 // Recalculate mContextMenuDestinationY because the context menu's final location may not be
123 // the same as its first location if it changed in height.
124 float contextMenuDestinationY =
125 mContextMenuSourceY + (mContextMenuFirstLocationY - contextMenuF inalLocation[1]);
126
127 Animation exitAnimation =
128 getScaleAnimation(false, mContextMenuSourceX, contextMenuDestina tionY);
129 exitAnimation.setAnimationListener(new AnimationListener() {
130
131 @Override
132 public void onAnimationStart(Animation animation) {}
133
134 @Override
135 public void onAnimationRepeat(Animation animation) {}
136
137 @Override
138 public void onAnimationEnd(Animation animation) {
139 ContextMenuDialog.super.dismiss();
140 }
141 });
142 mContentView.startAnimation(exitAnimation);
143 }
144
145 @Override
146 public boolean onTouchEvent(MotionEvent event) {
147 if (event.getAction() == MotionEvent.ACTION_DOWN) {
148 this.dismiss();
Theresa 2017/05/24 22:50:50 Just to confirm onTouchEvent() doesn't get called
Daniel Park 2017/05/25 17:12:37 from testing, it does get called when an item is c
Daniel Park 2017/05/25 17:12:37 Done.
149 }
150 return true;
151 }
152
153 /**
154 * @param isEnterAnimation Whether or not the animation will be for when the context menu enters
155 * or not.
Theresa 2017/05/24 22:50:50 nit: "Whether animation is for showing the context
Daniel Park 2017/05/25 17:12:37 Done.
156 * @param pivotX The X coordinate of the point about which the object is bei ng scaled, specified
157 * as an absolute number where 0 is the left edge.
158 * @param pivotY The Y coordinate of the point about which the object is bei ng scaled, specified
159 * as an absolute number where 0 is the top edge.
160 * @return Returns the scale animation for the context menu.
161 */
162 public Animation getScaleAnimation(boolean isEnterAnimation, float pivotX, f loat pivotY) {
163 float fromX = isEnterAnimation ? 0f : 1f;
164 float toX = isEnterAnimation ? 1f : 0f;
165 float fromY = fromX;
166 float toY = toX;
167
168 ScaleAnimation animation = new ScaleAnimation(
169 fromX, toX, fromY, toY, Animation.ABSOLUTE, pivotX, Animation.AB SOLUTE, pivotY);
170
171 long duration = isEnterAnimation ? ENTER_ANIMATION_DURATION : EXIT_ANIMA TION_DURATION;
172
173 animation.setDuration(duration);
174 animation.setInterpolator(new LinearOutSlowInInterpolator());
175 return animation;
176 }
177 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698