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

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: creating a new contextmenudialog constructor 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.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 dismiss().
Theresa 2017/05/30 16:16:07 nit: ... upon calling {@link #show()} and {@link #
Daniel Park 2017/05/30 17:40:40 Done.
27 */
28 public class ContextMenuDialog extends AlwaysDismissedDialog {
29 private static final int ENTER_ANIMATION_DURATION = 250;
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;
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,
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;
51 }
52
53 @Override
54 public void show() {
55 Window dialogWindow = this.getWindow();
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
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
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);
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
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();
133 }
134 return true;
Theresa 2017/05/30 16:16:07 This method should return true if the event was ha
Daniel Park 2017/05/30 17:40:40 Done.
135 }
136
137 /**
138 * @param isEnterAnimation Whether the animation to be returned is for showi ng the context menu
139 * as opposed to hiding it.
140 * @param pivotX The X coordinate of the point about which the object is bei ng scaled, specified
141 * as an absolute number where 0 is the left edge.
142 * @param pivotY The Y coordinate of the point about which the object is bei ng scaled, specified
143 * as an absolute number where 0 is the top edge.
144 * @return Returns the scale animation for the context menu.
145 */
146 public Animation getScaleAnimation(boolean isEnterAnimation, float pivotX, f loat pivotY) {
147 float fromX = isEnterAnimation ? 0f : 1f;
148 float toX = isEnterAnimation ? 1f : 0f;
149 float fromY = fromX;
150 float toY = toX;
151
152 ScaleAnimation animation = new ScaleAnimation(
153 fromX, toX, fromY, toY, Animation.ABSOLUTE, pivotX, Animation.AB SOLUTE, pivotY);
154
155 long duration = isEnterAnimation ? ENTER_ANIMATION_DURATION : EXIT_ANIMA TION_DURATION;
156
157 animation.setDuration(duration);
158 animation.setInterpolator(new LinearOutSlowInInterpolator());
159 return animation;
160 }
161 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698