Commit 605765aa authored by dgn's avatar dgn Committed by Commit bot

[NTP Client][Reland]Adjust the card display depending on the screen width.

Original issue's description:
> Changes the lines to go from always 2 to at most 2 by default, so that
> we don't show empty lines on very large screens.
> For smaller screens, the title can go up to 4 lines, and we then hide
> the description.
> On bigger screens, we add space on the side of the cards
>
> Measures used:
> < 360dp: Narrow -> 4 lines title
> >= 360dp: Regular -> 2 + 2 lines
> >= 600dp: Wide -> 2 + 2 lines, 48dp gutters around the cards
>
> Preview: https://goo.gl/photos/prJ42tvP4jzwiCn3A

Was reverted as https://codereview.chromium.org/2167973004/

Reason for revert:
> Broke Android compile:
> NewTabPageAdapterTest.java:162: error: constructor NewTabPageAdapter in
>   class NewTabPageAdapter cannot be applied to given types;
>   NewTabPageAdapter ntpa = new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge);
>                                  ^
>   required: NewTabPageManager,NewTabPageLayout,SnippetsBridge,UiConfig
>   found: NewTabPageManager,<null>,SnippetsBridge
>   reason: actual and formal argument lists differ in length

TBR=bauerb@chromium.org,mvanouwerkerk@chromium.org,peconn@chromium.org,dbeam@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
BUG=625628, 624333

Review-Url: https://codereview.chromium.org/2173723002
Cr-Commit-Position: refs/heads/master@{#407121}
parent 5507feeb
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_toStartOf="@+id/article_thumbnail" android:layout_toStartOf="@+id/article_thumbnail"
android:lines="2"
android:ellipsize="end" android:ellipsize="end"
android:textSize="16sp" android:textSize="16sp"
android:textColor="@color/snippets_headline_text_color" android:textColor="@color/snippets_headline_text_color"
...@@ -32,7 +31,7 @@ ...@@ -32,7 +31,7 @@
android:layout_below="@+id/article_headline" android:layout_below="@+id/article_headline"
android:layout_toStartOf="@+id/article_thumbnail" android:layout_toStartOf="@+id/article_thumbnail"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:lines="2" android:maxLines="2"
android:ellipsize="end" android:ellipsize="end"
android:textSize="14sp" android:textSize="14sp"
android:textColor="@color/snippets_text_color" android:textColor="@color/snippets_text_color"
......
...@@ -8,9 +8,9 @@ ...@@ -8,9 +8,9 @@
android:id="@+id/snippets_list_header" android:id="@+id/snippets_list_header"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/snippets_padding_and_peeking_card_height"
android:text="@string/snippets_header" android:text="@string/snippets_header"
android:textColor="@color/snippets_list_header_text_color" android:textColor="@color/snippets_list_header_text_color"
android:textSize="12sp" android:textSize="12sp"
android:paddingStart="@dimen/snippets_padding_and_peeking_card_height"
android:paddingTop="10dp" android:paddingTop="10dp"
android:gravity="start|center_vertical" /> android:gravity="start|center_vertical" />
...@@ -282,6 +282,7 @@ ...@@ -282,6 +282,7 @@
<dimen name="ntp_search_box_material_padding_left">2dp</dimen> <dimen name="ntp_search_box_material_padding_left">2dp</dimen>
<dimen name="ntp_search_box_material_padding_right">2dp</dimen> <dimen name="ntp_search_box_material_padding_right">2dp</dimen>
<dimen name="ntp_search_box_transition_length">16dp</dimen> <dimen name="ntp_search_box_transition_length">16dp</dimen>
<dimen name="ntp_wide_card_lateral_margins">48dp</dimen>
<dimen name="ntp_list_item_padding">16dp</dimen> <dimen name="ntp_list_item_padding">16dp</dimen>
<dimen name="ntp_list_item_min_height">48dp</dimen> <dimen name="ntp_list_item_min_height">48dp</dimen>
<dimen name="ntp_list_item_text_size">16sp</dimen> <dimen name="ntp_list_item_text_size">16sp</dimen>
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp;
/**
* Gets notified of changes in the display style.
*
* @see UiConfig.DisplayStyle
* @see UiConfig#getDisplayStyle()
* @see org.chromium.chrome.browser.ntp.cards.DisplayStyleObserverAdapter
*/
public interface DisplayStyleObserver {
void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisplayStyle);
}
...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.ntp; ...@@ -6,6 +6,7 @@ package org.chromium.chrome.browser.ntp;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources; import android.content.res.Resources;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
...@@ -95,6 +96,7 @@ public class NewTabPageView extends FrameLayout ...@@ -95,6 +96,7 @@ public class NewTabPageView extends FrameLayout
private OnSearchBoxScrollListener mSearchBoxScrollListener; private OnSearchBoxScrollListener mSearchBoxScrollListener;
private NewTabPageManager mManager; private NewTabPageManager mManager;
private UiConfig mUiConfig;
private MostVisitedDesign mMostVisitedDesign; private MostVisitedDesign mMostVisitedDesign;
private MostVisitedItem[] mMostVisitedItems; private MostVisitedItem[] mMostVisitedItems;
private boolean mFirstShow = true; private boolean mFirstShow = true;
...@@ -238,6 +240,7 @@ public class NewTabPageView extends FrameLayout ...@@ -238,6 +240,7 @@ public class NewTabPageView extends FrameLayout
public void initialize(NewTabPageManager manager, boolean searchProviderHasLogo, public void initialize(NewTabPageManager manager, boolean searchProviderHasLogo,
SnippetsBridge snippetsBridge) { SnippetsBridge snippetsBridge) {
mManager = manager; mManager = manager;
mUiConfig = new UiConfig(this);
ViewStub stub = (ViewStub) findViewById(R.id.new_tab_page_layout_stub); ViewStub stub = (ViewStub) findViewById(R.id.new_tab_page_layout_stub);
mUseCardsUi = snippetsBridge != null; mUseCardsUi = snippetsBridge != null;
...@@ -288,7 +291,8 @@ public class NewTabPageView extends FrameLayout ...@@ -288,7 +291,8 @@ public class NewTabPageView extends FrameLayout
// Set up snippets // Set up snippets
if (mUseCardsUi) { if (mUseCardsUi) {
mNewTabPageAdapter = new NewTabPageAdapter(mManager, mNewTabPageLayout, snippetsBridge); mNewTabPageAdapter =
new NewTabPageAdapter(mManager, mNewTabPageLayout, snippetsBridge, mUiConfig);
mRecyclerView.setAdapter(mNewTabPageAdapter); mRecyclerView.setAdapter(mNewTabPageAdapter);
// Set up swipe-to-dismiss // Set up swipe-to-dismiss
...@@ -1085,6 +1089,18 @@ public class NewTabPageView extends FrameLayout ...@@ -1085,6 +1089,18 @@ public class NewTabPageView extends FrameLayout
} }
} }
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// When the viewport configuration changes, we want to update the display style so that the
// observers are aware of the new available space. Another moment to do this update could
// be through a OnLayoutChangeListener, but then we get notified of the change after the
// layout pass, which means that the new style will only be visible after layout happens
// again. We prefer updating here to avoid having to require that additional layout pass.
mUiConfig.updateDisplayStyle();
}
private int getVerticalScroll() { private int getVerticalScroll() {
if (mUseCardsUi) { if (mUseCardsUi) {
return mRecyclerView.computeVerticalScrollOffset(); return mRecyclerView.computeVerticalScrollOffset();
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp;
import android.content.Context;
import android.support.annotation.IntDef;
import android.view.View;
import org.chromium.base.Log;
import org.chromium.ui.widget.Toast;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
/**
* Exposes general configuration info about the NTP UI.
*/
public class UiConfig {
/** The different supported UI setups. Observers can register to be notified of changes.*/
@Retention(RetentionPolicy.SOURCE)
@IntDef({DISPLAY_STYLE_UNDEFINED, DISPLAY_STYLE_NARROW, DISPLAY_STYLE_REGULAR,
DISPLAY_STYLE_WIDE})
public @interface DisplayStyle {}
public static final int DISPLAY_STYLE_UNDEFINED = -1;
public static final int DISPLAY_STYLE_NARROW = 0;
public static final int DISPLAY_STYLE_REGULAR = 1;
public static final int DISPLAY_STYLE_WIDE = 2;
private static final int REGULAR_CARD_MIN_WIDTH_DP = 360;
private static final int WIDE_CARD_MIN_WIDTH_DP = 600;
private static final String TAG = "Ntp";
private static final boolean DEBUG = false;
@DisplayStyle
private int mCurrentDisplayStyle;
private final List<DisplayStyleObserver> mObservers = new ArrayList<>();
private final Context mContext;
/**
* @param referenceView the View we observe to deduce the configuration from.
*/
public UiConfig(View referenceView) {
mContext = referenceView.getContext();
mCurrentDisplayStyle = computeDisplayStyleForCurrentConfig();
referenceView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
updateDisplayStyle();
}
@Override
public void onViewDetachedFromWindow(View v) {}
});
}
/**
* Registers a {@link DisplayStyleObserver}. It will be notified right away with the current
* display style.
*/
public void addObserver(DisplayStyleObserver observer) {
mObservers.add(observer);
observer.onDisplayStyleChanged(mCurrentDisplayStyle);
}
/**
* Refresh the display style, notify observers of changes.
*/
public void updateDisplayStyle() {
@DisplayStyle
int newDisplayStyle = computeDisplayStyleForCurrentConfig();
if (newDisplayStyle == mCurrentDisplayStyle) return;
mCurrentDisplayStyle = newDisplayStyle;
for (DisplayStyleObserver observer : mObservers) {
observer.onDisplayStyleChanged(newDisplayStyle);
}
}
@DisplayStyle
private int computeDisplayStyleForCurrentConfig() {
int widthDp = mContext.getResources().getConfiguration().screenWidthDp;
String debugString;
@DisplayStyle
int newDisplayStyle;
if (widthDp < REGULAR_CARD_MIN_WIDTH_DP) {
newDisplayStyle = DISPLAY_STYLE_NARROW;
if (DEBUG) debugString = String.format("DISPLAY_STYLE_NARROW (w=%ddp)", widthDp);
} else if (widthDp >= WIDE_CARD_MIN_WIDTH_DP) {
newDisplayStyle = DISPLAY_STYLE_WIDE;
if (DEBUG) debugString = String.format("DISPLAY_STYLE_WIDE (w=%ddp)", widthDp);
} else {
newDisplayStyle = DISPLAY_STYLE_REGULAR;
if (DEBUG) debugString = String.format("DISPLAY_STYLE_REGULAR (w=%ddp)", widthDp);
}
if (DEBUG) {
Log.d(TAG, debugString);
Toast.makeText(mContext, debugString, Toast.LENGTH_SHORT).show();
}
return newDisplayStyle;
}
}
...@@ -13,6 +13,7 @@ import android.view.ViewGroup; ...@@ -13,6 +13,7 @@ import android.view.ViewGroup;
import android.view.animation.Interpolator; import android.view.animation.Interpolator;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.UiConfig;
import org.chromium.chrome.browser.util.MathUtils; import org.chromium.chrome.browser.util.MathUtils;
/** /**
...@@ -27,6 +28,9 @@ import org.chromium.chrome.browser.util.MathUtils; ...@@ -27,6 +28,9 @@ import org.chromium.chrome.browser.util.MathUtils;
* {@link NewTabPageRecyclerView#showCardsFrom(int)}). Tap events in non-peeking state will be * {@link NewTabPageRecyclerView#showCardsFrom(int)}). Tap events in non-peeking state will be
* routed through {@link #onCardTapped()} for subclasses to override. * routed through {@link #onCardTapped()} for subclasses to override.
* *
* - Cards will get some lateral margins when the viewport is sufficiently wide.
* (see {@link UiConfig#DISPLAY_STYLE_WIDE})
*
* Note: If a subclass overrides {@link #onBindViewHolder(NewTabPageListItem)}, it should call the * Note: If a subclass overrides {@link #onBindViewHolder(NewTabPageListItem)}, it should call the
* parent implementation to reset the private state when a card is recycled. * parent implementation to reset the private state when a card is recycled.
*/ */
...@@ -45,6 +49,10 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -45,6 +49,10 @@ public class CardViewHolder extends NewTabPageViewHolder {
private final NewTabPageRecyclerView mRecyclerView; private final NewTabPageRecyclerView mRecyclerView;
private final UiConfig mUiConfig;
private final int mWideMarginSizePixels;
private final DisplayStyleObserverAdapter mDisplayStyleObserverAdapter;
/** /**
* Current padding value. The padding and the margins are manipulated together to create the * Current padding value. The padding and the margins are manipulated together to create the
* shrunk/peeking appearance of the cards. When the padding is low, the margins are high and * shrunk/peeking appearance of the cards. When the padding is low, the margins are high and
...@@ -57,9 +65,13 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -57,9 +65,13 @@ public class CardViewHolder extends NewTabPageViewHolder {
/** /**
* @param layoutId resource id of the layout to inflate and to use as card. * @param layoutId resource id of the layout to inflate and to use as card.
* @param recyclerView ViewGroup that will contain the newly created view. * @param recyclerView ViewGroup that will contain the newly created view.
* @param uiConfig The NTP UI configuration object used to adjust the card UI.
*/ */
public CardViewHolder(int layoutId, final NewTabPageRecyclerView recyclerView) { public CardViewHolder(
int layoutId, final NewTabPageRecyclerView recyclerView, UiConfig uiConfig) {
super(inflateView(layoutId, recyclerView)); super(inflateView(layoutId, recyclerView));
mWideMarginSizePixels = itemView.getResources().getDimensionPixelSize(
R.dimen.ntp_wide_card_lateral_margins);
mCards9PatchAdjustment = recyclerView.getResources().getDimensionPixelSize( mCards9PatchAdjustment = recyclerView.getResources().getDimensionPixelSize(
R.dimen.snippets_card_9_patch_adjustment); R.dimen.snippets_card_9_patch_adjustment);
...@@ -81,6 +93,9 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -81,6 +93,9 @@ public class CardViewHolder extends NewTabPageViewHolder {
} }
} }
}); });
mUiConfig = uiConfig;
mDisplayStyleObserverAdapter = MarginResizer.createWithViewAdapter(itemView, mUiConfig);
} }
/** /**
...@@ -164,13 +179,23 @@ public class CardViewHolder extends NewTabPageViewHolder { ...@@ -164,13 +179,23 @@ public class CardViewHolder extends NewTabPageViewHolder {
// Modify the padding so as the margin increases, the padding decreases, keeping the card's // Modify the padding so as the margin increases, the padding decreases, keeping the card's
// contents in the same position. The top and bottom remain the same. // contents in the same position. The top and bottom remain the same.
itemView.setPadding(mPeekPadding, mMaxPeekPadding, mPeekPadding, mMaxPeekPadding); int lateralPadding;
int lateralMargin;
if (mDisplayStyleObserverAdapter.getDisplayStyle() != UiConfig.DISPLAY_STYLE_WIDE) {
lateralPadding = mPeekPadding;
lateralMargin = mMaxPeekPadding - (mPeekPadding + mCards9PatchAdjustment);
} else {
lateralPadding = mMaxPeekPadding;
lateralMargin = mWideMarginSizePixels;
}
itemView.setPadding(lateralPadding, mMaxPeekPadding, lateralPadding, mMaxPeekPadding);
// This mCards9PatchAdjustment value will be used to adjust the padding so the card width // This mCards9PatchAdjustment value will be used to adjust the padding so the card width
// is the actual width not including the elevation shadow so we can have full bleed. // is the actual width not including the elevation shadow so we can have full bleed.
RecyclerView.LayoutParams params = getParams(); RecyclerView.LayoutParams params = getParams();
params.leftMargin = mMaxPeekPadding - (mPeekPadding + mCards9PatchAdjustment); params.leftMargin = lateralMargin;
params.rightMargin = mMaxPeekPadding - (mPeekPadding + mCards9PatchAdjustment); params.rightMargin = lateralMargin;
// Set the opacity of the card content to be 0 when peeking and 1 when full width. // Set the opacity of the card content to be 0 when peeking and 1 when full width.
int itemViewChildCount = ((ViewGroup) itemView).getChildCount(); int itemViewChildCount = ((ViewGroup) itemView).getChildCount();
......
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp.cards;
import android.view.View;
import org.chromium.chrome.browser.ntp.DisplayStyleObserver;
import org.chromium.chrome.browser.ntp.UiConfig;
/**
* Implementation of {@link DisplayStyleObserver} designed to play nicely with
* {@link android.support.v7.widget.RecyclerView}. It will not notify of changes when the
* associated view is not attached to the window.
*/
public class DisplayStyleObserverAdapter
implements DisplayStyleObserver, View.OnAttachStateChangeListener {
private final DisplayStyleObserver mObserver;
/** Current display style, gets updated as the UiConfig detects changes and notifies us. */
@UiConfig.DisplayStyle
private int mCurrentDisplayStyle;
/**
* Latest value that we transmitted to the adapted observer. If we didn't transfer any yet,
* the value is not a valid {@code DisplayStyle}
*/
@UiConfig.DisplayStyle
private Integer mNotifiedDisplayStyle;
private boolean mIsViewAttached;
/**
* @param view the view whose lifecycle is tracked to determine when to not fire the
* observer.
* @param config the {@link UiConfig} object to subscribe to.
* @param observer the observer to adapt. It's {#onDisplayStyleChanged} will be called when
* the configuration changes, provided that {@code view} is attached to the
* window.
*/
public DisplayStyleObserverAdapter(View view, UiConfig config, DisplayStyleObserver observer) {
mObserver = observer;
// TODO(dgn): getParent() is not a good way to test that, but isAttachedToWindow()
// requires API 19.
mIsViewAttached = view.getParent() != null;
view.addOnAttachStateChangeListener(this);
// This call will also assign the initial value to |mCurrentDisplayStyle|
config.addObserver(this);
}
@Override
public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisplayStyle) {
mCurrentDisplayStyle = newDisplayStyle;
if (!mIsViewAttached) return;
if (mNotifiedDisplayStyle != null && mCurrentDisplayStyle == mNotifiedDisplayStyle) return;
mNotifiedDisplayStyle = mCurrentDisplayStyle;
mObserver.onDisplayStyleChanged(mCurrentDisplayStyle);
}
@Override
public void onViewAttachedToWindow(View v) {
mIsViewAttached = true;
onDisplayStyleChanged(mCurrentDisplayStyle);
}
@Override
public void onViewDetachedFromWindow(View v) {
mIsViewAttached = false;
}
@UiConfig.DisplayStyle
public int getDisplayStyle() {
return mCurrentDisplayStyle;
}
}
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.ntp.cards;
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.DisplayStyleObserver;
import org.chromium.chrome.browser.ntp.UiConfig;
/**
* Adds lateral margins to the view when the display style is {@link UiConfig#DISPLAY_STYLE_WIDE}.
*/
public class MarginResizer implements DisplayStyleObserver {
private final int mWideMarginSizePixels;
private final View mView;
public static DisplayStyleObserverAdapter createWithViewAdapter(View view, UiConfig config) {
return new DisplayStyleObserverAdapter(view, config, new MarginResizer(view));
}
public MarginResizer(View view) {
mView = view;
mWideMarginSizePixels =
view.getResources().getDimensionPixelSize(R.dimen.ntp_wide_card_lateral_margins);
}
@Override
public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisplayStyle) {
MarginLayoutParams layoutParams = (MarginLayoutParams) mView.getLayoutParams();
if (newDisplayStyle == UiConfig.DISPLAY_STYLE_WIDE) {
layoutParams.setMargins(mWideMarginSizePixels, layoutParams.topMargin,
mWideMarginSizePixels, layoutParams.bottomMargin);
} else {
layoutParams.setMargins(0, layoutParams.topMargin, 0, layoutParams.bottomMargin);
}
}
}
...@@ -16,6 +16,7 @@ import org.chromium.base.Log; ...@@ -16,6 +16,7 @@ import org.chromium.base.Log;
import org.chromium.chrome.browser.ntp.NewTabPageLayout; import org.chromium.chrome.browser.ntp.NewTabPageLayout;
import org.chromium.chrome.browser.ntp.NewTabPageUma; import org.chromium.chrome.browser.ntp.NewTabPageUma;
import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
import org.chromium.chrome.browser.ntp.UiConfig;
import org.chromium.chrome.browser.ntp.snippets.DisabledReason; import org.chromium.chrome.browser.ntp.snippets.DisabledReason;
import org.chromium.chrome.browser.ntp.snippets.SnippetArticleListItem; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleListItem;
import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder; import org.chromium.chrome.browser.ntp.snippets.SnippetArticleViewHolder;
...@@ -46,6 +47,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements ...@@ -46,6 +47,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements
private final NewTabPageLayout mNewTabPageLayout; private final NewTabPageLayout mNewTabPageLayout;
private final AboveTheFoldListItem mAboveTheFoldListItem; private final AboveTheFoldListItem mAboveTheFoldListItem;
private final SnippetHeaderListItem mHeaderListItem; private final SnippetHeaderListItem mHeaderListItem;
private final UiConfig mUiConfig;
private StatusListItem mStatusListItem; private StatusListItem mStatusListItem;
private final List<NewTabPageListItem> mNewTabPageListItems; private final List<NewTabPageListItem> mNewTabPageListItems;
private final ItemTouchCallbacks mItemTouchCallbacks; private final ItemTouchCallbacks mItemTouchCallbacks;
...@@ -110,9 +112,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements ...@@ -110,9 +112,10 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements
* @param newTabPageLayout the layout encapsulating all the above-the-fold elements * @param newTabPageLayout the layout encapsulating all the above-the-fold elements
* (logo, search box, most visited tiles) * (logo, search box, most visited tiles)
* @param snippetsBridge the bridge to interact with the snippets service. * @param snippetsBridge the bridge to interact with the snippets service.
* @param uiConfig the NTP UI configuration, to be passed to created views.
*/ */
public NewTabPageAdapter(NewTabPageManager manager, NewTabPageLayout newTabPageLayout, public NewTabPageAdapter(NewTabPageManager manager, NewTabPageLayout newTabPageLayout,
SnippetsBridge snippetsBridge) { SnippetsBridge snippetsBridge, UiConfig uiConfig) {
mNewTabPageManager = manager; mNewTabPageManager = manager;
mNewTabPageLayout = newTabPageLayout; mNewTabPageLayout = newTabPageLayout;
mAboveTheFoldListItem = new AboveTheFoldListItem(); mAboveTheFoldListItem = new AboveTheFoldListItem();
...@@ -121,6 +124,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements ...@@ -121,6 +124,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements
mNewTabPageListItems = new ArrayList<NewTabPageListItem>(); mNewTabPageListItems = new ArrayList<NewTabPageListItem>();
mServiceStatus = DisabledReason.NONE; mServiceStatus = DisabledReason.NONE;
mSnippetsBridge = snippetsBridge; mSnippetsBridge = snippetsBridge;
mUiConfig = uiConfig;
mStatusListItem = StatusListItem.create(snippetsBridge.getDisabledReason(), this, manager); mStatusListItem = StatusListItem.create(snippetsBridge.getDisabledReason(), this, manager);
loadSnippets(new ArrayList<SnippetArticleListItem>()); loadSnippets(new ArrayList<SnippetArticleListItem>());
...@@ -192,12 +196,12 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements ...@@ -192,12 +196,12 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements
} }
if (viewType == NewTabPageListItem.VIEW_TYPE_HEADER) { if (viewType == NewTabPageListItem.VIEW_TYPE_HEADER) {
return new SnippetHeaderViewHolder( return new SnippetHeaderViewHolder(mRecyclerView, mUiConfig);
SnippetHeaderListItem.createView(parent), mRecyclerView);
} }
if (viewType == NewTabPageListItem.VIEW_TYPE_SNIPPET) { if (viewType == NewTabPageListItem.VIEW_TYPE_SNIPPET) {
return new SnippetArticleViewHolder(mRecyclerView, mNewTabPageManager, mSnippetsBridge); return new SnippetArticleViewHolder(
mRecyclerView, mNewTabPageManager, mSnippetsBridge, mUiConfig);
} }
if (viewType == NewTabPageListItem.VIEW_TYPE_SPACING) { if (viewType == NewTabPageListItem.VIEW_TYPE_SPACING) {
...@@ -205,7 +209,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements ...@@ -205,7 +209,7 @@ public class NewTabPageAdapter extends Adapter<NewTabPageViewHolder> implements
} }
if (viewType == NewTabPageListItem.VIEW_TYPE_STATUS) { if (viewType == NewTabPageListItem.VIEW_TYPE_STATUS) {
return new StatusListItem.ViewHolder(mRecyclerView); return new StatusListItem.ViewHolder(mRecyclerView, mUiConfig);
} }
return null; return null;
......
...@@ -13,6 +13,7 @@ import android.widget.TextView; ...@@ -13,6 +13,7 @@ import android.widget.TextView;
import org.chromium.base.Log; import org.chromium.base.Log;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
import org.chromium.chrome.browser.ntp.UiConfig;
import org.chromium.chrome.browser.ntp.snippets.DisabledReason; import org.chromium.chrome.browser.ntp.snippets.DisabledReason;
import org.chromium.chrome.browser.preferences.PreferencesLauncher; import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.signin.AccountSigninActivity; import org.chromium.chrome.browser.signin.AccountSigninActivity;
...@@ -33,8 +34,8 @@ public abstract class StatusListItem implements NewTabPageListItem { ...@@ -33,8 +34,8 @@ public abstract class StatusListItem implements NewTabPageListItem {
private final TextView mBodyView; private final TextView mBodyView;
private final Button mActionView; private final Button mActionView;
public ViewHolder(NewTabPageRecyclerView parent) { public ViewHolder(NewTabPageRecyclerView parent, UiConfig config) {
super(R.layout.new_tab_page_status_card, parent); super(R.layout.new_tab_page_status_card, parent, config);
mTitleView = (TextView) itemView.findViewById(R.id.status_title); mTitleView = (TextView) itemView.findViewById(R.id.status_title);
mBodyView = (TextView) itemView.findViewById(R.id.status_body); mBodyView = (TextView) itemView.findViewById(R.id.status_body);
mActionView = (Button) itemView.findViewById(R.id.status_action_button); mActionView = (Button) itemView.findViewById(R.id.status_action_button);
......
...@@ -24,9 +24,12 @@ import org.chromium.base.Callback; ...@@ -24,9 +24,12 @@ import org.chromium.base.Callback;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback; import org.chromium.chrome.browser.favicon.FaviconHelper.FaviconImageCallback;
import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallback; import org.chromium.chrome.browser.favicon.FaviconHelper.IconAvailabilityCallback;
import org.chromium.chrome.browser.ntp.DisplayStyleObserver;
import org.chromium.chrome.browser.ntp.NewTabPage; import org.chromium.chrome.browser.ntp.NewTabPage;
import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager; import org.chromium.chrome.browser.ntp.NewTabPageView.NewTabPageManager;
import org.chromium.chrome.browser.ntp.UiConfig;
import org.chromium.chrome.browser.ntp.cards.CardViewHolder; import org.chromium.chrome.browser.ntp.cards.CardViewHolder;
import org.chromium.chrome.browser.ntp.cards.DisplayStyleObserverAdapter;
import org.chromium.chrome.browser.ntp.cards.NewTabPageListItem; import org.chromium.chrome.browser.ntp.cards.NewTabPageListItem;
import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView; import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView;
import org.chromium.components.variations.VariationsAssociatedData; import org.chromium.components.variations.VariationsAssociatedData;
...@@ -69,10 +72,11 @@ public class SnippetArticleViewHolder extends CardViewHolder { ...@@ -69,10 +72,11 @@ public class SnippetArticleViewHolder extends CardViewHolder {
* @param parent The ViewGroup that is going to contain the newly created view. * @param parent The ViewGroup that is going to contain the newly created view.
* @param manager The NTPManager object used to open an article * @param manager The NTPManager object used to open an article
* @param snippetsBridge The SnippetsBridge used to retrieve the snippet thumbnails. * @param snippetsBridge The SnippetsBridge used to retrieve the snippet thumbnails.
* @param uiConfig The NTP UI configuration object used to adjust the article UI.
*/ */
public SnippetArticleViewHolder(NewTabPageRecyclerView parent, NewTabPageManager manager, public SnippetArticleViewHolder(NewTabPageRecyclerView parent, NewTabPageManager manager,
SnippetsBridge snippetsBridge) { SnippetsBridge snippetsBridge, UiConfig uiConfig) {
super(R.layout.new_tab_page_snippets_card, parent); super(R.layout.new_tab_page_snippets_card, parent, uiConfig);
mNewTabPageManager = manager; mNewTabPageManager = manager;
mSnippetsBridge = snippetsBridge; mSnippetsBridge = snippetsBridge;
...@@ -108,6 +112,19 @@ public class SnippetArticleViewHolder extends CardViewHolder { ...@@ -108,6 +112,19 @@ public class SnippetArticleViewHolder extends CardViewHolder {
} }
}); });
new DisplayStyleObserverAdapter(itemView, uiConfig, new DisplayStyleObserver() {
@Override
public void onDisplayStyleChanged(@UiConfig.DisplayStyle int newDisplayStyle) {
if (newDisplayStyle == UiConfig.DISPLAY_STYLE_NARROW) {
mHeadlineTextView.setMaxLines(4);
mArticleSnippetTextView.setVisibility(View.GONE);
} else {
mHeadlineTextView.setMaxLines(2);
mArticleSnippetTextView.setVisibility(View.VISIBLE);
}
}
});
mUseFaviconService = mUseFaviconService =
!PARAMETER_DISABLED_VALUE.equals(VariationsAssociatedData.getVariationParamValue( !PARAMETER_DISABLED_VALUE.equals(VariationsAssociatedData.getVariationParamValue(
NewTabPage.FIELD_TRIAL_NAME, PARAMETER_FAVICON_SERVICE_NAME)); NewTabPage.FIELD_TRIAL_NAME, PARAMETER_FAVICON_SERVICE_NAME));
......
...@@ -6,10 +6,10 @@ package org.chromium.chrome.browser.ntp.snippets; ...@@ -6,10 +6,10 @@ package org.chromium.chrome.browser.ntp.snippets;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.ntp.UiConfig;
import org.chromium.chrome.browser.ntp.cards.MarginResizer;
import org.chromium.chrome.browser.ntp.cards.NewTabPageListItem; import org.chromium.chrome.browser.ntp.cards.NewTabPageListItem;
import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView; import org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerView;
import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder; import org.chromium.chrome.browser.ntp.cards.NewTabPageViewHolder;
...@@ -27,20 +27,17 @@ public class SnippetHeaderViewHolder extends NewTabPageViewHolder { ...@@ -27,20 +27,17 @@ public class SnippetHeaderViewHolder extends NewTabPageViewHolder {
private SnippetHeaderListItem mHeader; private SnippetHeaderListItem mHeader;
public static View createView(ViewGroup parent) { public SnippetHeaderViewHolder(final NewTabPageRecyclerView recyclerView, UiConfig config) {
return LayoutInflater.from(parent.getContext()) super(LayoutInflater.from(recyclerView.getContext())
.inflate(R.layout.new_tab_page_snippets_card, parent, false); .inflate(R.layout.new_tab_page_snippets_header, recyclerView, false));
} mMaxSnippetHeaderHeight = itemView.getResources().getDimensionPixelSize(
public SnippetHeaderViewHolder(final View cardView, final NewTabPageRecyclerView recyclerView) {
super(cardView);
mMaxSnippetHeaderHeight = cardView.getResources().getDimensionPixelSize(
R.dimen.snippets_article_header_height); R.dimen.snippets_article_header_height);
mMaxPeekPadding = cardView.getResources().getDimensionPixelSize( mMaxPeekPadding = itemView.getResources().getDimensionPixelSize(
R.dimen.snippets_padding_and_peeking_card_height); R.dimen.snippets_padding_and_peeking_card_height);
mRecyclerView = recyclerView; mRecyclerView = recyclerView;
MarginResizer.createWithViewAdapter(itemView, config);
} }
@Override @Override
......
...@@ -492,6 +492,7 @@ chrome_java_sources = [ ...@@ -492,6 +492,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java", "java/src/org/chromium/chrome/browser/notifications/StandardNotificationBuilder.java",
"java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java", "java/src/org/chromium/chrome/browser/notifications/WebApkNotificationClient.java",
"java/src/org/chromium/chrome/browser/ntp/CurrentlyOpenTab.java", "java/src/org/chromium/chrome/browser/ntp/CurrentlyOpenTab.java",
"java/src/org/chromium/chrome/browser/ntp/DisplayStyleObserver.java",
"java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java", "java/src/org/chromium/chrome/browser/ntp/ForeignSessionHelper.java",
"java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java", "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPage.java",
"java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java", "java/src/org/chromium/chrome/browser/ntp/IncognitoNewTabPageView.java",
...@@ -520,6 +521,7 @@ chrome_java_sources = [ ...@@ -520,6 +521,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java", "java/src/org/chromium/chrome/browser/ntp/RecentlyClosedBridge.java",
"java/src/org/chromium/chrome/browser/ntp/TitleUtil.java", "java/src/org/chromium/chrome/browser/ntp/TitleUtil.java",
"java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleListItem.java",
"java/src/org/chromium/chrome/browser/ntp/UiConfig.java",
"java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetArticleViewHolder.java",
"java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderListItem.java",
"java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderViewHolder.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetHeaderViewHolder.java",
...@@ -528,6 +530,8 @@ chrome_java_sources = [ ...@@ -528,6 +530,8 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsLauncher.java", "java/src/org/chromium/chrome/browser/ntp/snippets/SnippetsLauncher.java",
"java/src/org/chromium/chrome/browser/ntp/cards/AboveTheFoldListItem.java", "java/src/org/chromium/chrome/browser/ntp/cards/AboveTheFoldListItem.java",
"java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java", "java/src/org/chromium/chrome/browser/ntp/cards/CardViewHolder.java",
"java/src/org/chromium/chrome/browser/ntp/cards/DisplayStyleObserverAdapter.java",
"java/src/org/chromium/chrome/browser/ntp/cards/MarginResizer.java",
"java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java", "java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapter.java",
"java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageListItem.java", "java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageListItem.java",
"java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java", "java/src/org/chromium/chrome/browser/ntp/cards/NewTabPageRecyclerView.java",
......
...@@ -63,7 +63,8 @@ public class NewTabPageAdapterTest { ...@@ -63,7 +63,8 @@ public class NewTabPageAdapterTest {
@Test @Test
@Feature({"Ntp"}) @Feature({"Ntp"})
public void testSnippetLoading() { public void testSnippetLoading() {
NewTabPageAdapter ntpa = new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge); NewTabPageAdapter ntpa =
new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge, null);
assertEquals(4, ntpa.getItemCount()); assertEquals(4, ntpa.getItemCount());
assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, ntpa.getItemViewType(0)); assertEquals(NewTabPageListItem.VIEW_TYPE_ABOVE_THE_FOLD, ntpa.getItemViewType(0));
...@@ -95,7 +96,8 @@ public class NewTabPageAdapterTest { ...@@ -95,7 +96,8 @@ public class NewTabPageAdapterTest {
@Test @Test
@Feature({"Ntp"}) @Feature({"Ntp"})
public void testSnippetLoadingInitiallyEmpty() { public void testSnippetLoadingInitiallyEmpty() {
NewTabPageAdapter ntpa = new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge); NewTabPageAdapter ntpa =
new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge, null);
// If we don't get anything, we should be in the same situation as the initial one. // If we don't get anything, we should be in the same situation as the initial one.
mSnippetsObserver.onSnippetsReceived(new ArrayList<SnippetArticleListItem>()); mSnippetsObserver.onSnippetsReceived(new ArrayList<SnippetArticleListItem>());
...@@ -128,7 +130,8 @@ public class NewTabPageAdapterTest { ...@@ -128,7 +130,8 @@ public class NewTabPageAdapterTest {
@Test @Test
@Feature({"Ntp"}) @Feature({"Ntp"})
public void testSnippetClearing() { public void testSnippetClearing() {
NewTabPageAdapter ntpa = new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge); NewTabPageAdapter ntpa =
new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge, null);
List<SnippetArticleListItem> snippets = createDummySnippets(); List<SnippetArticleListItem> snippets = createDummySnippets();
mSnippetsObserver.onSnippetsReceived(snippets); mSnippetsObserver.onSnippetsReceived(snippets);
...@@ -156,7 +159,8 @@ public class NewTabPageAdapterTest { ...@@ -156,7 +159,8 @@ public class NewTabPageAdapterTest {
@Test @Test
@Feature({"Ntp"}) @Feature({"Ntp"})
public void testSnippetLoadingBlock() { public void testSnippetLoadingBlock() {
NewTabPageAdapter ntpa = new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge); NewTabPageAdapter ntpa =
new NewTabPageAdapter(mNewTabPageManager, null, mSnippetsBridge, null);
List<SnippetArticleListItem> snippets = createDummySnippets(); List<SnippetArticleListItem> snippets = createDummySnippets();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment