OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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.ntp; | 5 package org.chromium.chrome.browser.ntp; |
6 | 6 |
7 import android.annotation.SuppressLint; | 7 import android.annotation.SuppressLint; |
8 import android.content.Context; | 8 import android.content.Context; |
9 import android.content.res.Configuration; | 9 import android.content.res.Configuration; |
10 import android.graphics.Canvas; | 10 import android.graphics.Canvas; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
51 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; | 51 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; |
52 import org.chromium.ui.base.DeviceFormFactor; | 52 import org.chromium.ui.base.DeviceFormFactor; |
53 | 53 |
54 /** | 54 /** |
55 * The native new tab page, represented by some basic data such as title and url , and an Android | 55 * The native new tab page, represented by some basic data such as title and url , and an Android |
56 * View that displays the page. | 56 * View that displays the page. |
57 */ | 57 */ |
58 public class NewTabPageView extends FrameLayout implements TileGroup.Observer { | 58 public class NewTabPageView extends FrameLayout implements TileGroup.Observer { |
59 private static final String TAG = "NewTabPageView"; | 59 private static final String TAG = "NewTabPageView"; |
60 | 60 |
61 private static final long SNAP_SCROLL_DELAY_MS = 30; | 61 private static final long SCROLL_RUNNABLE_DELAY_MS = 30; |
62 | 62 |
63 /** | 63 /** |
64 * Experiment parameter for the maximum number of tile suggestion rows to sh ow. | 64 * Experiment parameter for the maximum number of tile suggestion rows to sh ow. |
65 */ | 65 */ |
66 private static final String PARAM_NTP_MAX_TILE_ROWS = "ntp_max_tile_rows"; | 66 private static final String PARAM_NTP_MAX_TILE_ROWS = "ntp_max_tile_rows"; |
67 | 67 |
68 /** | 68 /** |
69 * Experiment parameter for the number of tile title lines to show. | 69 * Experiment parameter for the number of tile title lines to show. |
70 */ | 70 */ |
71 private static final String PARAM_NTP_TILE_TITLE_LINES = "ntp_tile_title_lin es"; | 71 private static final String PARAM_NTP_TILE_TITLE_LINES = "ntp_tile_title_lin es"; |
(...skipping 22 matching lines...) Expand all Loading... | |
94 | 94 |
95 private OnSearchBoxScrollListener mSearchBoxScrollListener; | 95 private OnSearchBoxScrollListener mSearchBoxScrollListener; |
96 | 96 |
97 private ChromeActivity mActivity; | 97 private ChromeActivity mActivity; |
98 private NewTabPageManager mManager; | 98 private NewTabPageManager mManager; |
99 private LogoView.Delegate mLogoDelegate; | 99 private LogoView.Delegate mLogoDelegate; |
100 private TileGroup.Delegate mTileGroupDelegate; | 100 private TileGroup.Delegate mTileGroupDelegate; |
101 private TileGroup mTileGroup; | 101 private TileGroup mTileGroup; |
102 private UiConfig mUiConfig; | 102 private UiConfig mUiConfig; |
103 private Runnable mSnapScrollRunnable; | 103 private Runnable mSnapScrollRunnable; |
104 private Runnable mUpdateSearchBoxOnScrollRunnable; | |
104 private boolean mFirstShow = true; | 105 private boolean mFirstShow = true; |
105 private boolean mSearchProviderHasLogo = true; | 106 private boolean mSearchProviderHasLogo = true; |
106 private boolean mPendingSnapScroll; | 107 private boolean mPendingSnapScroll; |
107 private boolean mInitialized; | 108 private boolean mInitialized; |
108 private int mLastScrollY = -1; | 109 private int mLastScrollY = -1; |
109 | 110 |
110 /** | 111 /** |
111 * The number of asynchronous tasks that need to complete before the page is done loading. | 112 * The number of asynchronous tasks that need to complete before the page is done loading. |
112 * This starts at one to track when the view is finished attaching to the wi ndow. | 113 * This starts at one to track when the view is finished attaching to the wi ndow. |
113 */ | 114 */ |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 | 190 |
190 mRecyclerView = new NewTabPageRecyclerView(getContext()); | 191 mRecyclerView = new NewTabPageRecyclerView(getContext()); |
191 mRecyclerView.setContainsLocationBar(manager.isLocationBarShownInNTP()); | 192 mRecyclerView.setContainsLocationBar(manager.isLocationBarShownInNTP()); |
192 addView(mRecyclerView); | 193 addView(mRecyclerView); |
193 | 194 |
194 // Don't attach now, the recyclerView itself will determine when to do i t. | 195 // Don't attach now, the recyclerView itself will determine when to do i t. |
195 mNewTabPageLayout = mRecyclerView.getAboveTheFoldView(); | 196 mNewTabPageLayout = mRecyclerView.getAboveTheFoldView(); |
196 | 197 |
197 mRecyclerView.setItemAnimator(new DefaultItemAnimator() { | 198 mRecyclerView.setItemAnimator(new DefaultItemAnimator() { |
198 @Override | 199 @Override |
200 public boolean animateMove(ViewHolder holder, int fromX, int fromY, int toX, int toY) { | |
201 // If |mNewTabPageLayout| is animated by the RecyclerView becaus e an item below it | |
Bernhard Bauer
2017/03/27 17:36:54
Stupid question, why doesn't it work to call updat
Michael van Ouwerkerk
2017/03/28 10:44:15
Because this method (animateMove) is called only o
| |
202 // was dismissed, avoid also manipulating its vertical offset in our scroll handling | |
203 // at the same time. The onScrolled() method is called when an i tem is dismissed and | |
204 // the item at the top of the viewport is repositioned. | |
205 if (holder.itemView == mNewTabPageLayout) setUrlFocusAnimationsD isabled(true); | |
206 | |
207 // Cancel any pending scroll update handling, a new one will be scheduled in | |
208 // onAnimationFinished(). | |
209 mRecyclerView.removeCallbacks(mUpdateSearchBoxOnScrollRunnable); | |
210 | |
211 return super.animateMove(holder, fromX, fromY, toX, toY); | |
212 } | |
213 | |
214 @Override | |
199 public void onAnimationFinished(ViewHolder viewHolder) { | 215 public void onAnimationFinished(ViewHolder viewHolder) { |
200 super.onAnimationFinished(viewHolder); | 216 super.onAnimationFinished(viewHolder); |
201 // When removing sections, because the animations are all transl ations, the | 217 |
202 // scroll events don't fire and we can get in the situation wher e the toolbar | 218 // When an item is dismissed, the items at the top of the viewpo rt might not move, |
203 // buttons disappear. | 219 // and onScrolled() might not be called. We can get in the situa tion where the |
204 updateSearchBoxOnScroll(); | 220 // toolbar buttons disappear, so schedule an update for it. This can be cancelled |
221 // from animateMove() in case |mNewTabPageLayout| will be moved. We don't know that | |
222 // from here, as the RecyclerView will animate multiple items wh en one is dismissed, | |
223 // and some will "finish" synchronously if they are already in t he correct place, | |
224 // before other moves have even been scheduled. | |
225 if (viewHolder.itemView == mNewTabPageLayout) setUrlFocusAnimati onsDisabled(false); | |
226 mRecyclerView.removeCallbacks(mUpdateSearchBoxOnScrollRunnable); | |
227 mRecyclerView.postDelayed( | |
228 mUpdateSearchBoxOnScrollRunnable, SCROLL_RUNNABLE_DELAY_ MS); | |
Bernhard Bauer
2017/03/27 17:36:54
Is there a reason to use that particular delay (wh
Michael van Ouwerkerk
2017/03/28 10:44:15
As it turns out, there's no need to use postDelaye
| |
205 } | 229 } |
206 }); | 230 }); |
207 | 231 |
208 mContextMenuManager = | 232 mContextMenuManager = |
209 new ContextMenuManager(mActivity, mManager.getNavigationDelegate (), mRecyclerView); | 233 new ContextMenuManager(mActivity, mManager.getNavigationDelegate (), mRecyclerView); |
210 mActivity.getWindowAndroid().addContextMenuCloseListener(mContextMenuMan ager); | 234 mActivity.getWindowAndroid().addContextMenuCloseListener(mContextMenuMan ager); |
211 manager.addDestructionObserver(new DestructionObserver() { | 235 manager.addDestructionObserver(new DestructionObserver() { |
212 @Override | 236 @Override |
213 public void onDestroy() { | 237 public void onDestroy() { |
214 mActivity.getWindowAndroid().removeContextMenuCloseListener(mCon textMenuManager); | 238 mActivity.getWindowAndroid().removeContextMenuCloseListener(mCon textMenuManager); |
215 } | 239 } |
216 }); | 240 }); |
217 | 241 |
218 OfflinePageBridge offlinePageBridge = | 242 OfflinePageBridge offlinePageBridge = |
219 OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()); | 243 OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()); |
220 | 244 |
221 mTileGridLayout = (TileGridLayout) mNewTabPageLayout.findViewById(R.id.t ile_grid_layout); | 245 mTileGridLayout = (TileGridLayout) mNewTabPageLayout.findViewById(R.id.t ile_grid_layout); |
222 mTileGridLayout.setMaxRows(getMaxTileRows(searchProviderHasLogo)); | 246 mTileGridLayout.setMaxRows(getMaxTileRows(searchProviderHasLogo)); |
223 mTileGridLayout.setMaxColumns(getMaxTileColumns()); | 247 mTileGridLayout.setMaxColumns(getMaxTileColumns()); |
224 mTileGroup = new TileGroup(mActivity, mManager, mContextMenuManager, mTi leGroupDelegate, | 248 mTileGroup = new TileGroup(mActivity, mManager, mContextMenuManager, mTi leGroupDelegate, |
225 /* observer = */ this, offlinePageBridge, getTileTitleLines()); | 249 /* observer = */ this, offlinePageBridge, getTileTitleLines()); |
226 | 250 |
227 mSearchProviderLogoView = | 251 mSearchProviderLogoView = |
228 (LogoView) mNewTabPageLayout.findViewById(R.id.search_provider_l ogo); | 252 (LogoView) mNewTabPageLayout.findViewById(R.id.search_provider_l ogo); |
229 mLogoDelegate = new LogoDelegateImpl(tab, mSearchProviderLogoView); | 253 mLogoDelegate = new LogoDelegateImpl(tab, mSearchProviderLogoView); |
230 mSearchBoxView = mNewTabPageLayout.findViewById(R.id.search_box); | 254 mSearchBoxView = mNewTabPageLayout.findViewById(R.id.search_box); |
231 mNoSearchLogoSpacer = mNewTabPageLayout.findViewById(R.id.no_search_logo _spacer); | 255 mNoSearchLogoSpacer = mNewTabPageLayout.findViewById(R.id.no_search_logo _spacer); |
232 | 256 |
233 mSnapScrollRunnable = new SnapScrollRunnable(); | 257 mSnapScrollRunnable = new SnapScrollRunnable(); |
258 mUpdateSearchBoxOnScrollRunnable = new UpdateSearchBoxOnScrollRunnable() ; | |
234 | 259 |
235 initializeSearchBoxTextView(); | 260 initializeSearchBoxTextView(); |
236 initializeVoiceSearchButton(); | 261 initializeVoiceSearchButton(); |
237 initializeLayoutChangeListeners(); | 262 initializeLayoutChangeListeners(); |
238 setSearchProviderHasLogo(searchProviderHasLogo); | 263 setSearchProviderHasLogo(searchProviderHasLogo); |
239 | 264 |
240 tab.addObserver(new EmptyTabObserver() { | 265 tab.addObserver(new EmptyTabObserver() { |
241 @Override | 266 @Override |
242 public void onShown(Tab tab) { | 267 public void onShown(Tab tab) { |
243 mTileGroup.onSwitchToForeground(); | 268 mTileGroup.onSwitchToForeground(); |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
487 | 512 |
488 mRecyclerView.setOnTouchListener(new OnTouchListener() { | 513 mRecyclerView.setOnTouchListener(new OnTouchListener() { |
489 @Override | 514 @Override |
490 @SuppressLint("ClickableViewAccessibility") | 515 @SuppressLint("ClickableViewAccessibility") |
491 public boolean onTouch(View v, MotionEvent event) { | 516 public boolean onTouch(View v, MotionEvent event) { |
492 mRecyclerView.removeCallbacks(mSnapScrollRunnable); | 517 mRecyclerView.removeCallbacks(mSnapScrollRunnable); |
493 | 518 |
494 if (event.getActionMasked() == MotionEvent.ACTION_CANCEL | 519 if (event.getActionMasked() == MotionEvent.ACTION_CANCEL |
495 || event.getActionMasked() == MotionEvent.ACTION_UP) { | 520 || event.getActionMasked() == MotionEvent.ACTION_UP) { |
496 mPendingSnapScroll = true; | 521 mPendingSnapScroll = true; |
497 mRecyclerView.postDelayed(mSnapScrollRunnable, SNAP_SCROLL_D ELAY_MS); | 522 mRecyclerView.postDelayed(mSnapScrollRunnable, SCROLL_RUNNAB LE_DELAY_MS); |
498 } else { | 523 } else { |
499 mPendingSnapScroll = false; | 524 mPendingSnapScroll = false; |
500 } | 525 } |
501 return false; | 526 return false; |
502 } | 527 } |
503 }); | 528 }); |
504 TraceEvent.end(TAG + ".setupScrollHandling()"); | 529 TraceEvent.end(TAG + ".setupScrollHandling()"); |
505 } | 530 } |
506 | 531 |
507 private void handleScroll() { | 532 private void handleScroll() { |
508 if (mPendingSnapScroll) { | 533 if (mPendingSnapScroll) { |
509 mRecyclerView.removeCallbacks(mSnapScrollRunnable); | 534 mRecyclerView.removeCallbacks(mSnapScrollRunnable); |
510 mRecyclerView.postDelayed(mSnapScrollRunnable, SNAP_SCROLL_DELAY_MS) ; | 535 mRecyclerView.postDelayed(mSnapScrollRunnable, SCROLL_RUNNABLE_DELAY _MS); |
511 } | 536 } |
512 updateSearchBoxOnScroll(); | 537 updateSearchBoxOnScroll(); |
513 mRecyclerView.updatePeekingCardAndHeader(); | 538 mRecyclerView.updatePeekingCardAndHeader(); |
514 } | 539 } |
515 | 540 |
516 /** | 541 /** |
517 * Decrements the count of pending load tasks and notifies the manager when the page load | 542 * Decrements the count of pending load tasks and notifies the manager when the page load |
518 * is complete. | 543 * is complete. |
519 */ | 544 */ |
520 private void loadTaskCompleted() { | 545 private void loadTaskCompleted() { |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
928 | 953 |
929 private class SnapScrollRunnable implements Runnable { | 954 private class SnapScrollRunnable implements Runnable { |
930 @Override | 955 @Override |
931 public void run() { | 956 public void run() { |
932 assert mPendingSnapScroll; | 957 assert mPendingSnapScroll; |
933 mPendingSnapScroll = false; | 958 mPendingSnapScroll = false; |
934 | 959 |
935 mRecyclerView.snapScroll(mSearchBoxView, getHeight()); | 960 mRecyclerView.snapScroll(mSearchBoxView, getHeight()); |
936 } | 961 } |
937 } | 962 } |
963 | |
964 private class UpdateSearchBoxOnScrollRunnable implements Runnable { | |
965 @Override | |
966 public void run() { | |
967 updateSearchBoxOnScroll(); | |
968 } | |
969 } | |
938 } | 970 } |
OLD | NEW |