Chromium Code Reviews| Index: chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java |
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java |
| index f09d1c43398b0dfd220e95c5b0166a01496f2bd5..3ceec5c92eab607d2aa4e54821dc5a9e707080ea 100644 |
| --- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java |
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java |
| @@ -5,6 +5,7 @@ |
| package org.chromium.chrome.browser.ntp.cards; |
| import android.content.Context; |
| +import android.content.res.Resources; |
| import android.support.v7.widget.LinearLayoutManager; |
| import android.support.v7.widget.RecyclerView; |
| import android.util.AttributeSet; |
| @@ -14,13 +15,33 @@ |
| import android.view.inputmethod.EditorInfo; |
| import android.view.inputmethod.InputConnection; |
| +import org.chromium.chrome.R; |
| + |
| /** |
| * Simple wrapper on top of a RecyclerView that will acquire focus when tapped. Ensures the |
| * New Tab page receives focus when clicked. |
| */ |
| public class NewTabPageRecyclerView extends RecyclerView { |
| - private GestureDetector mGestureDetector; |
| - private LinearLayoutManager mLayoutManager; |
| + /** |
| + * Minimum height of the bottom spacing item. |
| + */ |
| + private static final int MIN_BOTTOM_SPACING = 0; |
| + |
| + /** |
| + * Position in the adapter of the item we snap the scroll at, when switching between above and |
| + * below the fold. |
| + */ |
| + private static final int SNAP_ITEM_ADAPTER_POSITION = 1; |
| + |
| + private final GestureDetector mGestureDetector; |
| + private final LinearLayoutManager mLayoutManager; |
| + private final int mToolbarHeight; |
| + |
| + /** |
| + * Total height of the items being dismissed, that we track so that the bottom spacer can |
| + * compensate for their removal animation, and avoid the scroll position to shift around. |
|
gone
2016/05/16 23:47:29
nit: "Total height of the items being dismissed.
dgn
2016/05/17 09:16:53
Done.
|
| + */ |
| + private int mCompensationHeight; |
| /** |
| * Constructor needed to inflate from XML. |
| @@ -28,6 +49,7 @@ |
| public NewTabPageRecyclerView(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| + mCompensationHeight = 0; |
| mGestureDetector = |
| new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() { |
| @Override |
| @@ -39,6 +61,10 @@ public boolean onSingleTapUp(MotionEvent e) { |
| }); |
| mLayoutManager = new LinearLayoutManager(getContext()); |
| setLayoutManager(mLayoutManager); |
| + |
| + Resources res = context.getResources(); |
| + mToolbarHeight = res.getDimensionPixelSize(R.dimen.toolbar_height_no_shadow) |
| + + res.getDimensionPixelSize(R.dimen.toolbar_progress_bar_height); |
| } |
| public boolean isFirstItemVisible() { |
| @@ -78,4 +104,50 @@ public InputConnection onCreateInputConnection(EditorInfo outAttrs) { |
| public LinearLayoutManager getLinearLayoutManager() { |
| return mLayoutManager; |
| } |
| + |
| + /** |
| + * Updates the space added at the end of the list to make sure the above/below the fold |
| + * distinction can be preserved. |
| + */ |
| + public void refreshBottomSpacing() { |
| + ViewHolder bottomSpacingViewHolder = |
| + findViewHolderForAdapterPosition(getAdapter().getItemCount() - 1); |
| + |
| + // It might not be in the layout yet if it's not visible or ready to be displayed. |
| + if (bottomSpacingViewHolder == null) return; |
| + |
| + assert bottomSpacingViewHolder.getItemViewType() == NewTabPageListItem.VIEW_TYPE_SPACING; |
| + bottomSpacingViewHolder.itemView.requestLayout(); |
| + } |
| + |
| + /** |
| + * Calculates the height of the bottom spacing item, such that there is always enough content |
| + * below the fold to push the header to align with the top of the screen. |
|
gone
2016/05/16 23:47:29
nit: "below the fold to push the header up to the
dgn
2016/05/17 09:16:54
Done.
|
| + */ |
| + int calculateBottomSpacing() { |
| + int firstVisiblePos = mLayoutManager.findFirstVisibleItemPosition(); |
| + |
| + // We have enough items to fill the view, since the snap point item is not even visible. |
| + if (firstVisiblePos > SNAP_ITEM_ADAPTER_POSITION) return MIN_BOTTOM_SPACING; |
| + |
| + // The spacing item is the last item, the last content item is directly above that. |
| + int lastContentItemPosition = getAdapter().getItemCount() - 2; |
| + int contentHeight = |
| + findViewHolderForAdapterPosition(lastContentItemPosition).itemView.getBottom() |
| + - findViewHolderForAdapterPosition(SNAP_ITEM_ADAPTER_POSITION).itemView.getTop(); |
| + int bottomSpacing = getHeight() - mToolbarHeight - contentHeight + mCompensationHeight; |
| + |
| + return Math.max(MIN_BOTTOM_SPACING, bottomSpacing); |
| + } |
| + |
| + /** Called when an item is in the process of being removed from the view. */ |
| + void onItemDismissStarted(View itemView) { |
| + mCompensationHeight += itemView.getHeight(); |
| + } |
| + |
| + /** Notify that an item has been removed from the view. */ |
|
gone
2016/05/16 23:47:29
nit: This doesn't do any notifying.
"Called when a
dgn
2016/05/17 09:16:54
Done.
|
| + void onItemDismissFinished(View itemView) { |
| + mCompensationHeight -= itemView.getHeight(); |
| + assert mCompensationHeight >= 0; |
| + } |
| } |