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

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, 6 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.Color;
9 import android.graphics.Rect;
10 import android.graphics.drawable.ColorDrawable;
11 import android.support.v4.view.animation.LinearOutSlowInInterpolator;
12 import android.view.MotionEvent;
13 import android.view.View;
14 import android.view.View.OnLayoutChangeListener;
15 import android.view.ViewGroup;
16 import android.view.ViewGroup.LayoutParams;
17 import android.view.Window;
18 import android.view.animation.Animation;
19 import android.view.animation.Animation.AnimationListener;
20 import android.view.animation.ScaleAnimation;
21
22 import org.chromium.content.browser.RenderCoordinates;
23
24 /**
25 * ContextMenuDialog is a subclass of AlwaysDismissedDialog that ensures that th e proper scale
26 * animation is played upon calling {@link #show()} and {@link #dismiss()}.
27 */
28 public class ContextMenuDialog extends AlwaysDismissedDialog {
29 private static final int ENTER_ANIMATION_DURATION = 250;
Ted C 2017/05/30 23:04:04 suffix of _MS to indicate milliseconds nit, I thi
Daniel Park 2017/05/31 18:19:39 Done.
30 // Exit animation duration should be set to 60% of the enter animation durat ion.
31 private static final int EXIT_ANIMATION_DURATION = 150;
32
33 private final Activity mActivity;
34
35 private View mContentView;
36 private float mContextMenuSourceX;
Ted C 2017/05/30 23:04:04 same comment about the suffixes of Px or Dp
Daniel Park 2017/05/31 18:19:39 Done.
37 private float mContextMenuSourceY;
38 private float mTouchPointX;
39 private float mTouchPointY;
40 private int mContextMenuFirstLocationY;
41 private RenderCoordinates mRenderCoordinates;
42
43 public ContextMenuDialog(Activity ownerActivity, int theme, float touchPoint X,
Ted C 2017/05/30 23:04:04 javadoc
Daniel Park 2017/05/31 18:19:39 Done.
44 float touchPointY, View contentView, RenderCoordinates renderCoordin ates) {
45 super(ownerActivity, theme);
46 mActivity = ownerActivity;
47 mTouchPointX = touchPointX;
48 mTouchPointY = touchPointY;
49 mContentView = contentView;
50 mRenderCoordinates = renderCoordinates;
Ted C 2017/05/30 23:04:04 looks like many if not all of these could also be
Daniel Park 2017/05/31 18:19:39 Done.
51 }
52
53 @Override
54 public void show() {
55 Window dialogWindow = this.getWindow();
Ted C 2017/05/30 23:04:04 no need for this.
Daniel Park 2017/05/31 18:19:39 Done.
56 dialogWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)) ;
57 dialogWindow.setLayout(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PAR ENT);
58
59 mContentView.setVisibility(View.INVISIBLE);
60 mContentView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
61
Ted C 2017/05/30 23:04:04 remove blank line
Daniel Park 2017/05/31 18:19:39 Done.
62 @Override
63 public void onLayoutChange(View v, int left, int top, int right, int bottom,
64 int oldLeft, int oldTop, int oldRight, int oldBottom) {
65 ViewGroup group = (ViewGroup) v;
66 for (int i = 0; i < group.getChildCount(); i++) {
67 if (group.getChildAt(i).getHeight() == 0
Ted C 2017/05/30 23:04:04 I think you can use getMeasuredHeight() == 0 here
Daniel Park 2017/05/31 18:19:39 Done.
68 && group.getChildAt(i).getVisibility() == View.VISIB LE) {
69 // Return early because not all the views have been meas ured, so animation
70 // pivots will be off.
71 return;
72 }
73 }
74 mContentView.setVisibility(View.VISIBLE);
75 startEnterAnimation();
76 mContentView.removeOnLayoutChangeListener(this);
77 }
78 });
79 super.show();
80 }
81
82 private void startEnterAnimation() {
83 Rect rectangle = new Rect();
84 Window window = mActivity.getWindow();
85 window.getDecorView().getWindowVisibleDisplayFrame(rectangle);
86
87 float xOffset = rectangle.left;
88 float yOffset = rectangle.top + mRenderCoordinates.getContentOffsetYPix( );
89
90 int[] currentLocationOnScreen = new int[2];
91 mContentView.getLocationOnScreen(currentLocationOnScreen);
Ted C 2017/05/30 23:04:04 you should try this on a phone on a sight with the
Daniel Park 2017/05/31 18:19:39 Done.
Daniel Park 2017/05/31 18:19:39 the starting points are all correct.
92
93 mContextMenuFirstLocationY = currentLocationOnScreen[1];
94
95 mContextMenuSourceX = mTouchPointX - currentLocationOnScreen[0] + xOffse t;
96 mContextMenuSourceY = mTouchPointY - currentLocationOnScreen[1] + yOffse t;
97
98 Animation animation = getScaleAnimation(true, mContextMenuSourceX, mCont extMenuSourceY);
99 mContentView.startAnimation(animation);
100 }
101
102 @Override
103 public void dismiss() {
104 int[] contextMenuFinalLocation = new int[2];
105 mContentView.getLocationOnScreen(contextMenuFinalLocation);
106 // Recalculate mContextMenuDestinationY because the context menu's final location may not be
107 // the same as its first location if it changed in height.
108 float contextMenuDestinationY =
109 mContextMenuSourceY + (mContextMenuFirstLocationY - contextMenuF inalLocation[1]);
110
111 Animation exitAnimation =
112 getScaleAnimation(false, mContextMenuSourceX, contextMenuDestina tionY);
113 exitAnimation.setAnimationListener(new AnimationListener() {
114
Ted C 2017/05/30 23:04:05 remove blank line
Daniel Park 2017/05/31 18:19:39 Done.
115 @Override
116 public void onAnimationStart(Animation animation) {}
117
118 @Override
119 public void onAnimationRepeat(Animation animation) {}
120
121 @Override
122 public void onAnimationEnd(Animation animation) {
123 ContextMenuDialog.super.dismiss();
124 }
125 });
126 mContentView.startAnimation(exitAnimation);
127 }
128
129 @Override
130 public boolean onTouchEvent(MotionEvent event) {
131 if (event.getAction() == MotionEvent.ACTION_DOWN) {
132 this.dismiss();
Ted C 2017/05/30 23:04:04 can drop "this."
Daniel Park 2017/05/31 18:19:39 Done.
133 return true;
134 }
135 return false;
136 }
137
138 /**
139 * @param isEnterAnimation Whether the animation to be returned is for showi ng the context menu
140 * as opposed to hiding it.
141 * @param pivotX The X coordinate of the point about which the object is bei ng scaled, specified
142 * as an absolute number where 0 is the left edge.
143 * @param pivotY The Y coordinate of the point about which the object is bei ng scaled, specified
144 * as an absolute number where 0 is the top edge.
145 * @return Returns the scale animation for the context menu.
146 */
147 public Animation getScaleAnimation(boolean isEnterAnimation, float pivotX, f loat pivotY) {
148 float fromX = isEnterAnimation ? 0f : 1f;
149 float toX = isEnterAnimation ? 1f : 0f;
150 float fromY = fromX;
151 float toY = toX;
152
153 ScaleAnimation animation = new ScaleAnimation(
154 fromX, toX, fromY, toY, Animation.ABSOLUTE, pivotX, Animation.AB SOLUTE, pivotY);
155
156 long duration = isEnterAnimation ? ENTER_ANIMATION_DURATION : EXIT_ANIMA TION_DURATION;
157
158 animation.setDuration(duration);
159 animation.setInterpolator(new LinearOutSlowInInterpolator());
160 return animation;
161 }
162 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698