OLD | NEW |
---|---|
(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 } | |
OLD | NEW |