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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after 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 |
| 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.post(mUpdateSearchBoxOnScrollRunnable); |
205 } | 228 } |
206 }); | 229 }); |
207 | 230 |
208 mContextMenuManager = | 231 mContextMenuManager = |
209 new ContextMenuManager(mActivity, mManager.getNavigationDelegate
(), mRecyclerView); | 232 new ContextMenuManager(mActivity, mManager.getNavigationDelegate
(), mRecyclerView); |
210 mActivity.getWindowAndroid().addContextMenuCloseListener(mContextMenuMan
ager); | 233 mActivity.getWindowAndroid().addContextMenuCloseListener(mContextMenuMan
ager); |
211 manager.addDestructionObserver(new DestructionObserver() { | 234 manager.addDestructionObserver(new DestructionObserver() { |
212 @Override | 235 @Override |
213 public void onDestroy() { | 236 public void onDestroy() { |
214 mActivity.getWindowAndroid().removeContextMenuCloseListener(mCon
textMenuManager); | 237 mActivity.getWindowAndroid().removeContextMenuCloseListener(mCon
textMenuManager); |
215 } | 238 } |
216 }); | 239 }); |
217 | 240 |
218 OfflinePageBridge offlinePageBridge = | 241 OfflinePageBridge offlinePageBridge = |
219 OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()); | 242 OfflinePageBridge.getForProfile(Profile.getLastUsedProfile()); |
220 | 243 |
221 mTileGridLayout = (TileGridLayout) mNewTabPageLayout.findViewById(R.id.t
ile_grid_layout); | 244 mTileGridLayout = (TileGridLayout) mNewTabPageLayout.findViewById(R.id.t
ile_grid_layout); |
222 mTileGridLayout.setMaxRows(getMaxTileRows(searchProviderHasLogo)); | 245 mTileGridLayout.setMaxRows(getMaxTileRows(searchProviderHasLogo)); |
223 mTileGridLayout.setMaxColumns(getMaxTileColumns()); | 246 mTileGridLayout.setMaxColumns(getMaxTileColumns()); |
224 mTileGroup = new TileGroup(mActivity, mManager, mContextMenuManager, mTi
leGroupDelegate, | 247 mTileGroup = new TileGroup(mActivity, mManager, mContextMenuManager, mTi
leGroupDelegate, |
225 /* observer = */ this, offlinePageBridge, getTileTitleLines()); | 248 /* observer = */ this, offlinePageBridge, getTileTitleLines()); |
226 | 249 |
227 mSearchProviderLogoView = | 250 mSearchProviderLogoView = |
228 (LogoView) mNewTabPageLayout.findViewById(R.id.search_provider_l
ogo); | 251 (LogoView) mNewTabPageLayout.findViewById(R.id.search_provider_l
ogo); |
229 mLogoDelegate = new LogoDelegateImpl(tab, mSearchProviderLogoView); | 252 mLogoDelegate = new LogoDelegateImpl(tab, mSearchProviderLogoView); |
230 mSearchBoxView = mNewTabPageLayout.findViewById(R.id.search_box); | 253 mSearchBoxView = mNewTabPageLayout.findViewById(R.id.search_box); |
231 mNoSearchLogoSpacer = mNewTabPageLayout.findViewById(R.id.no_search_logo
_spacer); | 254 mNoSearchLogoSpacer = mNewTabPageLayout.findViewById(R.id.no_search_logo
_spacer); |
232 | 255 |
233 mSnapScrollRunnable = new SnapScrollRunnable(); | 256 mSnapScrollRunnable = new SnapScrollRunnable(); |
| 257 mUpdateSearchBoxOnScrollRunnable = new UpdateSearchBoxOnScrollRunnable()
; |
234 | 258 |
235 initializeSearchBoxTextView(); | 259 initializeSearchBoxTextView(); |
236 initializeVoiceSearchButton(); | 260 initializeVoiceSearchButton(); |
237 initializeLayoutChangeListeners(); | 261 initializeLayoutChangeListeners(); |
238 setSearchProviderHasLogo(searchProviderHasLogo); | 262 setSearchProviderHasLogo(searchProviderHasLogo); |
239 | 263 |
240 tab.addObserver(new EmptyTabObserver() { | 264 tab.addObserver(new EmptyTabObserver() { |
241 @Override | 265 @Override |
242 public void onShown(Tab tab) { | 266 public void onShown(Tab tab) { |
243 mTileGroup.onSwitchToForeground(); | 267 mTileGroup.onSwitchToForeground(); |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 | 952 |
929 private class SnapScrollRunnable implements Runnable { | 953 private class SnapScrollRunnable implements Runnable { |
930 @Override | 954 @Override |
931 public void run() { | 955 public void run() { |
932 assert mPendingSnapScroll; | 956 assert mPendingSnapScroll; |
933 mPendingSnapScroll = false; | 957 mPendingSnapScroll = false; |
934 | 958 |
935 mRecyclerView.snapScroll(mSearchBoxView, getHeight()); | 959 mRecyclerView.snapScroll(mSearchBoxView, getHeight()); |
936 } | 960 } |
937 } | 961 } |
| 962 |
| 963 private class UpdateSearchBoxOnScrollRunnable implements Runnable { |
| 964 @Override |
| 965 public void run() { |
| 966 updateSearchBoxOnScroll(); |
| 967 } |
| 968 } |
938 } | 969 } |
OLD | NEW |