OLD | NEW |
---|---|
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 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 | 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.searchwidget; | 5 package org.chromium.chrome.browser.searchwidget; |
6 | 6 |
7 import android.animation.Animator; | |
8 import android.animation.AnimatorListenerAdapter; | |
9 import android.animation.ValueAnimator; | |
10 import android.content.Intent; | 7 import android.content.Intent; |
11 import android.graphics.Rect; | 8 import android.graphics.Rect; |
12 import android.graphics.drawable.Drawable; | 9 import android.graphics.drawable.Drawable; |
13 import android.net.Uri; | 10 import android.net.Uri; |
14 import android.os.Handler; | 11 import android.os.Handler; |
15 import android.support.customtabs.CustomTabsIntent; | 12 import android.support.customtabs.CustomTabsIntent; |
16 import android.support.v4.app.ActivityOptionsCompat; | 13 import android.support.v4.app.ActivityOptionsCompat; |
17 import android.text.TextUtils; | 14 import android.text.TextUtils; |
18 import android.view.Gravity; | 15 import android.view.LayoutInflater; |
19 import android.view.View; | 16 import android.view.View; |
20 import android.view.View.MeasureSpec; | |
21 import android.view.ViewGroup; | 17 import android.view.ViewGroup; |
22 import android.view.ViewGroup.LayoutParams; | |
23 import android.view.ViewStub; | |
24 import android.widget.FrameLayout; | |
25 | 18 |
26 import org.chromium.base.ApiCompatibilityUtils; | 19 import org.chromium.base.ApiCompatibilityUtils; |
27 import org.chromium.base.ContextUtils; | 20 import org.chromium.base.ContextUtils; |
28 import org.chromium.chrome.R; | 21 import org.chromium.chrome.R; |
29 import org.chromium.chrome.browser.IntentHandler; | 22 import org.chromium.chrome.browser.IntentHandler; |
30 import org.chromium.chrome.browser.WebContentsFactory; | 23 import org.chromium.chrome.browser.WebContentsFactory; |
31 import org.chromium.chrome.browser.WindowDelegate; | 24 import org.chromium.chrome.browser.WindowDelegate; |
32 import org.chromium.chrome.browser.customtabs.CustomTabsConnection; | 25 import org.chromium.chrome.browser.customtabs.CustomTabsConnection; |
33 import org.chromium.chrome.browser.document.ChromeLauncherActivity; | 26 import org.chromium.chrome.browser.document.ChromeLauncherActivity; |
34 import org.chromium.chrome.browser.init.AsyncInitializationActivity; | 27 import org.chromium.chrome.browser.init.AsyncInitializationActivity; |
35 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; | 28 import org.chromium.chrome.browser.init.ChromeBrowserInitializer; |
36 import org.chromium.chrome.browser.omnibox.AutocompleteController; | 29 import org.chromium.chrome.browser.omnibox.AutocompleteController; |
37 import org.chromium.chrome.browser.omnibox.UrlBar; | 30 import org.chromium.chrome.browser.omnibox.UrlBar; |
38 import org.chromium.chrome.browser.profiles.Profile; | 31 import org.chromium.chrome.browser.profiles.Profile; |
39 import org.chromium.chrome.browser.snackbar.SnackbarManager; | 32 import org.chromium.chrome.browser.snackbar.SnackbarManager; |
40 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable; | 33 import org.chromium.chrome.browser.snackbar.SnackbarManager.SnackbarManageable; |
41 import org.chromium.chrome.browser.tab.Tab; | 34 import org.chromium.chrome.browser.tab.Tab; |
42 import org.chromium.chrome.browser.tab.TabDelegateFactory; | 35 import org.chromium.chrome.browser.tab.TabDelegateFactory; |
43 import org.chromium.chrome.browser.tab.TabIdManager; | 36 import org.chromium.chrome.browser.tab.TabIdManager; |
44 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; | 37 import org.chromium.chrome.browser.tabmodel.TabModel.TabLaunchType; |
45 import org.chromium.chrome.browser.util.IntentUtils; | 38 import org.chromium.chrome.browser.util.IntentUtils; |
46 import org.chromium.chrome.browser.widget.FadingBackgroundView; | |
47 import org.chromium.components.url_formatter.UrlFormatter; | 39 import org.chromium.components.url_formatter.UrlFormatter; |
48 import org.chromium.content_public.browser.LoadUrlParams; | 40 import org.chromium.content_public.browser.LoadUrlParams; |
49 import org.chromium.ui.UiUtils; | 41 import org.chromium.ui.UiUtils; |
50 import org.chromium.ui.base.ActivityWindowAndroid; | 42 import org.chromium.ui.base.ActivityWindowAndroid; |
51 | 43 |
52 /** Prototype that queries the user's default search engine and shows autocomple te suggestions. */ | 44 /** Prototype that queries the user's default search engine and shows autocomple te suggestions. */ |
53 public class SearchActivity extends AsyncInitializationActivity | 45 public class SearchActivity extends AsyncInitializationActivity |
54 implements SnackbarManageable, SearchLocationBarLayout.Delegate, | 46 implements SnackbarManageable, SearchActivityLocationBarLayout.Delegate, |
55 View.OnLayoutChangeListener { | 47 View.OnLayoutChangeListener { |
56 private static final String TAG = "searchwidget"; | 48 private static final String TAG = "searchwidget"; |
57 | 49 |
58 /** How long the animation should run for. */ | |
59 private static final int ANIMATION_DURATION_MS = 200; | |
60 | |
61 /** Padding gleaned from the background Drawable of the search box. */ | 50 /** Padding gleaned from the background Drawable of the search box. */ |
62 private final Rect mSearchBoxPadding = new Rect(); | 51 private final Rect mSearchBoxPadding = new Rect(); |
63 | 52 |
64 /** Location of the search box on the home screen. */ | |
65 private Rect mSearchBoxWidgetBounds; | |
66 | |
67 /** Small margin/padding used for the search box. */ | |
68 private int mSpacingSmall; | |
69 | |
70 /** Medium margin/padding used for the search box. */ | 53 /** Medium margin/padding used for the search box. */ |
71 private int mSpacingMedium; | 54 private int mSpacingMedium; |
72 | 55 |
73 /** Large margin/padding used for the search box. */ | 56 /** Large margin/padding used for the search box. */ |
74 private int mSpacingLarge; | 57 private int mSpacingLarge; |
75 | 58 |
76 /** | |
77 * View that the omnibox suggestion list anchors to. This is different from the main search box | |
78 * because the upstream LocationBarLayout code expects a full white box inst ead of a floating | |
79 * box with shadows. | |
80 */ | |
81 private View mAnchorView; | |
82 | |
83 /** See {@link BoxAnimatorScrim}. */ | |
84 private BoxAnimatorScrim mScrimView; | |
85 | |
86 /** Main content view. */ | 59 /** Main content view. */ |
87 private ViewGroup mContentView; | 60 private ViewGroup mContentView; |
88 | 61 |
89 /** Whether or not the library has begun loading. */ | |
90 private boolean mIsNativeLoading; | |
91 | |
92 /** Whether the native library has been loaded. */ | 62 /** Whether the native library has been loaded. */ |
93 private boolean mIsNativeReady; | 63 private boolean mIsNativeReady; |
94 | 64 |
95 /** Input submitted before before the native library was loaded. */ | 65 /** Input submitted before before the native library was loaded. */ |
96 private String mQueuedUrl; | 66 private String mQueuedUrl; |
97 | 67 |
98 /** Animates the SearchActivity's controls moving into place. */ | |
99 private ValueAnimator mAnimator; | |
100 | |
101 /** The View that represents the search box. */ | 68 /** The View that represents the search box. */ |
102 private SearchLocationBarLayout mSearchBox; | 69 private SearchActivityLocationBarLayout mSearchBox; |
103 | 70 |
104 private UrlBar mUrlBar; | 71 private UrlBar mUrlBar; |
105 | 72 |
106 private SearchBoxDataProvider mSearchBoxDataProvider; | 73 private SearchBoxDataProvider mSearchBoxDataProvider; |
107 | 74 |
108 private SnackbarManager mSnackbarManager; | 75 private SnackbarManager mSnackbarManager; |
109 private ActivityWindowAndroid mWindowAndroid; | 76 private ActivityWindowAndroid mWindowAndroid; |
110 private Tab mTab; | 77 private Tab mTab; |
111 | 78 |
112 @Override | 79 @Override |
113 public void backKeyPressed() { | 80 public void backKeyPressed() { |
114 finish(); | 81 finish(); |
115 } | 82 } |
116 | 83 |
117 @Override | 84 @Override |
118 public void onStop() { | 85 public void onStop() { |
119 finish(); | 86 finish(); |
120 super.onStop(); | 87 super.onStop(); |
121 } | 88 } |
122 | 89 |
123 @Override | 90 @Override |
124 public void finish() { | 91 public void finish() { |
125 if (SearchWidgetProvider.ANIMATE_TRANSITION) { | |
126 // Update the search widgets so that they all show up as opaque agai n. | |
127 SearchWidgetProvider.setLaunchingWidgetId(SearchWidgetProvider.INVAL ID_WIDGET_ID); | |
128 SearchWidgetProvider.updateAllWidgets(); | |
129 } | |
130 | |
131 super.finish(); | 92 super.finish(); |
132 overridePendingTransition(0, android.R.anim.fade_out); | 93 overridePendingTransition(0, android.R.anim.fade_out); |
133 } | 94 } |
134 | 95 |
135 @Override | 96 @Override |
136 protected boolean shouldDelayBrowserStartup() { | 97 protected boolean shouldDelayBrowserStartup() { |
137 return true; | 98 return true; |
138 } | 99 } |
139 | 100 |
140 @Override | 101 @Override |
141 public boolean onActivityResultWithNative(int requestCode, int resultCode, I ntent intent) { | 102 public boolean onActivityResultWithNative(int requestCode, int resultCode, I ntent intent) { |
142 if (super.onActivityResultWithNative(requestCode, resultCode, intent)) r eturn true; | 103 if (super.onActivityResultWithNative(requestCode, resultCode, intent)) r eturn true; |
143 boolean result = mWindowAndroid.onActivityResult(requestCode, resultCode , intent); | 104 boolean result = mWindowAndroid.onActivityResult(requestCode, resultCode , intent); |
144 | 105 |
145 // The voice query should have completed. If the voice recognition isn' t confident about | 106 // The voice query should have completed. If the voice recognition isn' t confident about |
146 // what it heard, it puts the query into the omnibox. We need to focus it at that point. | 107 // what it heard, it puts the query into the omnibox. We need to focus it at that point. |
147 if (mUrlBar != null) focusTextBox(false); | 108 if (mUrlBar != null) focusTextBox(false); |
148 | 109 |
149 return result; | 110 return result; |
150 } | 111 } |
151 | 112 |
152 @Override | 113 @Override |
153 protected void setContentView() { | 114 protected void setContentView() { |
154 initializeDimensions(); | 115 initializeDimensions(); |
155 | 116 |
156 mWindowAndroid = new ActivityWindowAndroid(this); | 117 mWindowAndroid = new ActivityWindowAndroid(this); |
157 mSnackbarManager = new SnackbarManager(this); | 118 mSnackbarManager = new SnackbarManager(this); |
119 mSearchBoxDataProvider = new SearchBoxDataProvider(); | |
158 | 120 |
159 // Build the Views that {@link SearchLocationBarLayout} expects to exist . | 121 mContentView = createContentView(mSearchBox); |
160 ViewStub resultsStub = new ViewStub(this); | 122 mContentView.setOnClickListener(new View.OnClickListener() { |
161 resultsStub.setId(R.id.omnibox_results_container_stub); | |
162 resultsStub.setLayoutResource(R.layout.omnibox_results_container); | |
163 | |
164 // The FadingBackgroundView isn't used here, but is still animated by th e LocationBarLayout. | |
165 // This interferes with the animation we need to show the widget moving to the right place. | |
166 FadingBackgroundView fadingView = new FadingBackgroundView(this, null) { | |
167 @Override | |
168 public void showFadingOverlay() {} | |
169 @Override | |
170 public void hideFadingOverlay(boolean fadeOut) {} | |
171 }; | |
172 | |
173 fadingView.setId(R.id.fading_focus_target); | |
174 FrameLayout.LayoutParams fadingBackgroundLayoutParams = new FrameLayout. LayoutParams(0, 0); | |
175 | |
176 // Add an empty view to prevent crashing. | |
177 ViewGroup bottomContainer = new FrameLayout(this); | |
178 bottomContainer.setId(R.id.bottom_container); | |
179 | |
180 // Build the search box, set it to invisible until the animation is done . | |
181 mSearchBox = new SearchLocationBarLayout(this, null); | |
182 mSearchBox.setDelegate(this); | |
183 mSearchBox.setVisibility(mSearchBoxWidgetBounds == null ? View.VISIBLE : View.INVISIBLE); | |
184 mSearchBox.setBackgroundResource(R.drawable.card_single); | |
185 mSearchBox.setPadding(mSpacingLarge, mSpacingMedium, mSpacingLarge, mSpa cingMedium); | |
186 mSearchBox.initializeControls(new WindowDelegate(getWindow()), mWindowAn droid); | |
187 mSearchBox.setUrlBarFocusable(true); | |
188 mSearchBoxDataProvider = new SearchBoxDataProvider(); | |
189 mSearchBox.setToolbarDataProvider(mSearchBoxDataProvider); | |
190 FrameLayout.LayoutParams searchParams = | |
191 new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutPa rams.WRAP_CONTENT); | |
192 ApiCompatibilityUtils.setMarginStart(searchParams, mSpacingSmall); | |
193 ApiCompatibilityUtils.setMarginEnd(searchParams, mSpacingSmall); | |
194 searchParams.topMargin = mSpacingSmall; | |
195 | |
196 // The scrim animates the search box moving into place. | |
197 mScrimView = new BoxAnimatorScrim(this, null); | |
198 mScrimView.setOnClickListener(new View.OnClickListener() { | |
199 @Override | 123 @Override |
200 public void onClick(View v) { | 124 public void onClick(View v) { |
201 // Don't allow clicking on the scrim until the animation complet es. | |
202 if (mScrimView.getInterpolatedValue() < 1.0f) return; | |
203 | |
204 // Finish the Activity if the user clicks on the scrim. | 125 // Finish the Activity if the user clicks on the scrim. |
205 finish(); | 126 finish(); |
206 } | 127 } |
207 }); | 128 }); |
208 if (!SearchWidgetProvider.ANIMATE_TRANSITION) mScrimView.setInterpolated Value(1.0f); | |
209 | 129 |
210 // The anchor view puts the omnibox suggestions in the correct place, vi sually. | 130 // Build the search box. |
211 mAnchorView = new View(this); | 131 mSearchBox = (SearchActivityLocationBarLayout) mContentView.findViewById ( |
212 mAnchorView.setId(R.id.toolbar); | 132 R.id.search_location_bar); |
213 mAnchorView.setClickable(true); | 133 mSearchBox.setDelegate(this); |
214 FrameLayout.LayoutParams anchorParams = | 134 mSearchBox.setPadding(mSpacingLarge, mSpacingMedium, mSpacingLarge, mSpa cingMedium); |
215 new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutPa rams.WRAP_CONTENT); | 135 mSearchBox.initializeControls(new WindowDelegate(getWindow()), mWindowAn droid); |
216 anchorParams.gravity = Gravity.CENTER_HORIZONTAL; | 136 mSearchBox.setUrlBarFocusable(true); |
137 mSearchBox.setToolbarDataProvider(mSearchBoxDataProvider); | |
217 | 138 |
218 // Initialize and build the View hierarchy. | |
219 mContentView = createContentView(mSearchBox); | |
220 mContentView.addView(fadingView, fadingBackgroundLayoutParams); | |
221 mContentView.addView(mScrimView); | |
222 mContentView.addView(resultsStub); | |
223 mContentView.addView(mAnchorView, anchorParams); | |
224 mContentView.addView(mSearchBox, searchParams); | |
225 mContentView.addView(bottomContainer); | |
226 setContentView(mContentView); | 139 setContentView(mContentView); |
227 mUrlBar = (UrlBar) mSearchBox.findViewById(R.id.url_bar); | 140 mUrlBar = (UrlBar) mSearchBox.findViewById(R.id.url_bar); |
228 | |
229 mSearchBox.setShowCachedZeroSuggestResults(true); | |
230 } | 141 } |
231 | 142 |
232 @Override | 143 @Override |
233 public void finishNativeInitialization() { | 144 public void finishNativeInitialization() { |
234 super.finishNativeInitialization(); | 145 super.finishNativeInitialization(); |
235 mIsNativeReady = true; | 146 mIsNativeReady = true; |
236 | 147 |
237 mTab = new Tab(TabIdManager.getInstance().generateValidId(Tab.INVALID_TA B_ID), | 148 mTab = new Tab(TabIdManager.getInstance().generateValidId(Tab.INVALID_TA B_ID), |
238 Tab.INVALID_TAB_ID, false, this, mWindowAndroid, TabLaunchType.F ROM_EXTERNAL_APP, | 149 Tab.INVALID_TAB_ID, false, this, mWindowAndroid, TabLaunchType.F ROM_EXTERNAL_APP, |
239 null, null); | 150 null, null); |
240 mTab.initialize(WebContentsFactory.createWebContents(false, false), null , | 151 mTab.initialize(WebContentsFactory.createWebContents(false, false), null , |
241 new TabDelegateFactory(), false, false); | 152 new TabDelegateFactory(), false, false); |
242 mTab.loadUrl(new LoadUrlParams("about:blank")); | 153 mTab.loadUrl(new LoadUrlParams("about:blank")); |
243 mSearchBoxDataProvider.onNativeLibraryReady(mTab); | 154 mSearchBoxDataProvider.onNativeLibraryReady(mTab); |
244 mSearchBox.onNativeLibraryReady(); | 155 mSearchBox.onNativeLibraryReady(); |
245 mSearchBox.setAutocompleteProfile(Profile.getLastUsedProfile().getOrigin alProfile()); | 156 mSearchBox.setAutocompleteProfile(Profile.getLastUsedProfile().getOrigin alProfile()); |
157 mSearchBox.setShowCachedZeroSuggestResults(true); | |
246 | 158 |
247 if (mQueuedUrl != null) loadUrl(mQueuedUrl); | 159 if (mQueuedUrl != null) loadUrl(mQueuedUrl); |
248 | 160 |
249 new Handler().post(new Runnable() { | 161 new Handler().post(new Runnable() { |
250 @Override | 162 @Override |
251 public void run() { | 163 public void run() { |
252 onDeferredStartup(); | 164 onDeferredStartup(); |
253 } | 165 } |
254 }); | 166 }); |
255 } | 167 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 focusTextBox(true); | 205 focusTextBox(true); |
294 } | 206 } |
295 } | 207 } |
296 | 208 |
297 @Override | 209 @Override |
298 protected void onDestroy() { | 210 protected void onDestroy() { |
299 if (mTab != null && mTab.isInitialized()) mTab.destroy(); | 211 if (mTab != null && mTab.isInitialized()) mTab.destroy(); |
300 super.onDestroy(); | 212 super.onDestroy(); |
301 } | 213 } |
302 | 214 |
303 private void focusTextBox(boolean clearQuery) { | 215 private void focusTextBox(boolean clearQuery) { |
Yusuf
2017/04/07 18:08:28
maybe this should be in the SearchLocationBar clas
gone
2017/04/07 18:15:26
Talked offline:
There's a lot more cleanup to be d
| |
304 if (mIsNativeReady) mSearchBox.onUrlFocusChange(true); | 216 if (mIsNativeReady) mSearchBox.onUrlFocusChange(true); |
217 | |
218 if (clearQuery) { | |
219 mUrlBar.setIgnoreTextChangesForAutocomplete(true); | |
220 mUrlBar.setUrl("", null); | |
221 mUrlBar.setIgnoreTextChangesForAutocomplete(false); | |
222 } | |
305 mUrlBar.setCursorVisible(true); | 223 mUrlBar.setCursorVisible(true); |
306 mUrlBar.setIgnoreTextChangesForAutocomplete(true); | |
307 if (clearQuery) mUrlBar.setUrl("", null); | |
308 mUrlBar.setIgnoreTextChangesForAutocomplete(false); | |
309 mUrlBar.setSelection(0, mUrlBar.getText().length()); | 224 mUrlBar.setSelection(0, mUrlBar.getText().length()); |
310 new Handler().post(new Runnable() { | 225 new Handler().post(new Runnable() { |
311 @Override | 226 @Override |
312 public void run() { | 227 public void run() { |
313 UiUtils.showKeyboard(mUrlBar); | 228 UiUtils.showKeyboard(mUrlBar); |
314 } | 229 } |
315 }); | 230 }); |
316 } | 231 } |
317 | 232 |
318 @Override | 233 @Override |
(...skipping 28 matching lines...) Expand all Loading... | |
347 startActivity(intent, | 262 startActivity(intent, |
348 ActivityOptionsCompat | 263 ActivityOptionsCompat |
349 .makeCustomAnimation(this, android.R.anim.fade_in, andro id.R.anim.fade_out) | 264 .makeCustomAnimation(this, android.R.anim.fade_in, andro id.R.anim.fade_out) |
350 .toBundle()); | 265 .toBundle()); |
351 finish(); | 266 finish(); |
352 } | 267 } |
353 | 268 |
354 private ViewGroup createContentView(final View searchBox) { | 269 private ViewGroup createContentView(final View searchBox) { |
355 assert mContentView == null; | 270 assert mContentView == null; |
356 | 271 |
357 ViewGroup contentView = new FrameLayout(this) { | 272 ViewGroup contentView = (ViewGroup) LayoutInflater.from(this).inflate( |
358 @Override | 273 R.layout.search_activity, null, false); |
359 public void onMeasure(int widthSpec, int heightSpec) { | |
360 super.onMeasure(widthSpec, heightSpec); | |
361 if (mAnchorView == null) return; | |
362 | |
363 // Calculate how big the box is without shadow-induced padding. | |
364 FrameLayout.LayoutParams anchorParams = | |
365 (FrameLayout.LayoutParams) mAnchorView.getLayoutParams() ; | |
366 int anchorViewWidth = searchBox.getMeasuredWidth() - mSearchBoxP adding.left | |
367 - mSearchBoxPadding.right; | |
368 int anchorViewHeight = | |
369 mSpacingSmall + mSearchBox.getMeasuredHeight() - mSearch BoxPadding.bottom; | |
370 if (anchorParams.width == anchorViewWidth | |
371 && anchorParams.height == anchorViewHeight) { | |
372 return; | |
373 } | |
374 | |
375 // Move the anchor view up a little bit as a dirty hack until we can add a | |
376 // dimension. This allows the suggestion list to move up past th e rounded corners of | |
377 // the search box. | |
378 anchorParams.topMargin = -(mSpacingSmall / 4); | |
379 anchorParams.width = anchorViewWidth; | |
380 anchorParams.height = anchorViewHeight; | |
381 | |
382 // Measure the anchor view to match the search box's height with out its side or | |
383 // bottom shadow padding. This isn't exactly what we need, but i t's hard to get the | |
384 // correct behavior because LocationBarLayout overrides how the suggestions are | |
385 // laid out. | |
386 int anchorWidthSpec = | |
387 MeasureSpec.makeMeasureSpec(anchorViewWidth, MeasureSpec .EXACTLY); | |
388 int anchorHeightSpec = | |
389 MeasureSpec.makeMeasureSpec(anchorViewHeight, MeasureSpe c.EXACTLY); | |
390 measureChild(mAnchorView, anchorWidthSpec, anchorHeightSpec); | |
391 } | |
392 }; | |
393 | |
394 contentView.addOnLayoutChangeListener(this); | 274 contentView.addOnLayoutChangeListener(this); |
395 contentView.setId(R.id.control_container); | |
396 return contentView; | 275 return contentView; |
397 } | 276 } |
398 | 277 |
399 @Override | 278 @Override |
400 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, | 279 public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, |
401 int oldTop, int oldRight, int oldBottom) { | 280 int oldTop, int oldRight, int oldBottom) { |
402 if (mSearchBoxWidgetBounds != null) { | |
403 if (mAnimator == null) initializeAnimation(); | |
404 } else { | |
405 // If there's no animation, then we can load the library immediately without worrying | |
406 // about jank. | |
407 beginLoadingLibrary(); | |
408 } | |
409 mContentView.removeOnLayoutChangeListener(this); | 281 mContentView.removeOnLayoutChangeListener(this); |
282 beginLoadingLibrary(); | |
410 } | 283 } |
411 | 284 |
412 private void initializeDimensions() { | 285 private void initializeDimensions() { |
413 mSearchBoxWidgetBounds = getIntent().getSourceBounds(); | |
414 | |
415 // Cache the padding of the Drawable that is used as the background for the search box. | 286 // Cache the padding of the Drawable that is used as the background for the search box. |
416 Drawable searchBackground = | 287 Drawable searchBackground = |
417 ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.car d_single); | 288 ApiCompatibilityUtils.getDrawable(getResources(), R.drawable.car d_single); |
418 searchBackground.getPadding(mSearchBoxPadding); | 289 searchBackground.getPadding(mSearchBoxPadding); |
419 | 290 |
420 // TODO(dfalcantara): Add values to the XML files instead of reusing ran dom ones. | 291 // TODO(dfalcantara): Add values to the XML files instead of reusing ran dom ones. |
421 mSpacingSmall = getResources().getDimensionPixelSize( | |
422 R.dimen.tablet_toolbar_start_padding_no_buttons); | |
423 mSpacingMedium = | 292 mSpacingMedium = |
424 getResources().getDimensionPixelSize(R.dimen.location_bar_incogn ito_badge_padding); | 293 getResources().getDimensionPixelSize(R.dimen.location_bar_incogn ito_badge_padding); |
425 mSpacingLarge = | 294 mSpacingLarge = |
426 getResources().getDimensionPixelSize(R.dimen.contextual_search_p eek_promo_padding); | 295 getResources().getDimensionPixelSize(R.dimen.contextual_search_p eek_promo_padding); |
427 } | 296 } |
428 | 297 |
429 private void initializeAnimation() { | |
430 assert SearchWidgetProvider.ANIMATE_TRANSITION; | |
431 | |
432 // The bounds of the home screen widget are given in window space coordi nates, so they need | |
433 // to be converted into conrdinates that are relative from the root View . The converted | |
434 // bounds are used to animate the box moving from its widget location to the location at the | |
435 // top of the screen. | |
436 int[] rootWindowLocation = new int[2]; | |
437 mContentView.getLocationInWindow(rootWindowLocation); | |
438 | |
439 final Rect sourceRect = new Rect(); | |
440 sourceRect.left = mSearchBoxWidgetBounds.left - rootWindowLocation[0]; | |
441 sourceRect.right = mSearchBoxWidgetBounds.right - rootWindowLocation[0]; | |
442 sourceRect.top = mSearchBoxWidgetBounds.top - rootWindowLocation[1]; | |
443 sourceRect.bottom = mSearchBoxWidgetBounds.bottom - rootWindowLocation[1 ]; | |
444 | |
445 int[] targetBoxLocation = new int[2]; | |
446 mSearchBox.getLocationInWindow(targetBoxLocation); | |
447 final Rect targetRect = new Rect(); | |
448 targetRect.left = targetBoxLocation[0] - rootWindowLocation[0]; | |
449 targetRect.right = targetRect.left + mSearchBox.getMeasuredWidth(); | |
450 targetRect.top = targetBoxLocation[1] - rootWindowLocation[1]; | |
451 targetRect.bottom = targetRect.top + mSearchBox.getMeasuredHeight(); | |
452 | |
453 mScrimView.setAnimationRects(sourceRect, targetRect); | |
454 | |
455 mAnimator = ValueAnimator.ofFloat(0, 1); | |
456 mAnimator.setDuration(ANIMATION_DURATION_MS); | |
457 mAnimator.addListener(new AnimatorListenerAdapter() { | |
458 @Override | |
459 public void onAnimationStart(Animator animation) { | |
460 // Make the widget on the homescreen hide itself. | |
461 SearchWidgetProvider.updateAllWidgets(); | |
462 } | |
463 | |
464 @Override | |
465 public void onAnimationEnd(Animator animation) { | |
466 // Defer loading the library until the box is in the right place to prevent jank. | |
467 beginLoadingLibrary(); | |
468 } | |
469 }); | |
470 mAnimator.addUpdateListener(mScrimView); | |
471 | |
472 new Handler().post(new Runnable() { | |
473 @Override | |
474 public void run() { | |
475 mAnimator.start(); | |
476 } | |
477 }); | |
478 } | |
479 | |
480 private void beginLoadingLibrary() { | 298 private void beginLoadingLibrary() { |
481 if (mIsNativeLoading) return; | |
482 mIsNativeLoading = true; | |
483 | |
484 // Show the real search box and let the user type in it. | |
485 mScrimView.setInterpolatedValue(1.0f); | |
486 mSearchBox.setVisibility(View.VISIBLE); | |
487 beginQuery(); | 299 beginQuery(); |
488 mHandler.post(new Runnable() { | 300 mHandler.post(new Runnable() { |
489 @Override | 301 @Override |
490 public void run() { | 302 public void run() { |
491 mSearchBox.showCachedZeroSuggestResultsIfAvailable(); | 303 mSearchBox.showCachedZeroSuggestResultsIfAvailable(); |
492 } | 304 } |
493 }); | 305 }); |
494 ChromeBrowserInitializer.getInstance(getApplicationContext()) | 306 ChromeBrowserInitializer.getInstance(getApplicationContext()) |
495 .handlePreNativeStartup(SearchActivity.this); | 307 .handlePreNativeStartup(SearchActivity.this); |
496 } | 308 } |
497 } | 309 } |
OLD | NEW |