| Index: chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
|
| index c3666d32b26d5fed18ba16607a5ed86d46850fb5..75a6889e318187b0da96c4ad96d91eb8a97812b0 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/selection/SelectableListLayout.java
|
| @@ -7,12 +7,16 @@ package org.chromium.chrome.browser.widget.selection;
|
| import android.content.Context;
|
| import android.content.res.Configuration;
|
| import android.content.res.Resources;
|
| +import android.graphics.Rect;
|
| import android.graphics.drawable.Drawable;
|
| +import android.support.annotation.VisibleForTesting;
|
| import android.support.v4.widget.DrawerLayout;
|
| import android.support.v7.widget.LinearLayoutManager;
|
| import android.support.v7.widget.RecyclerView;
|
| import android.support.v7.widget.RecyclerView.Adapter;
|
| import android.support.v7.widget.RecyclerView.AdapterDataObserver;
|
| +import android.support.v7.widget.RecyclerView.ItemAnimator;
|
| +import android.support.v7.widget.RecyclerView.OnScrollListener;
|
| import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
|
| import android.util.AttributeSet;
|
| import android.view.LayoutInflater;
|
| @@ -30,8 +34,11 @@ import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver;
|
| import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle;
|
| import org.chromium.chrome.browser.widget.displaystyle.UiConfig;
|
| import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle;
|
| +import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver;
|
| import org.chromium.ui.base.DeviceFormFactor;
|
|
|
| +import java.util.List;
|
| +
|
| import javax.annotation.Nullable;
|
|
|
| /**
|
| @@ -43,15 +50,47 @@ import javax.annotation.Nullable;
|
| *
|
| * @param <E> The type of the selectable items this layout holds.
|
| */
|
| -public class SelectableListLayout<E> extends RelativeLayout implements DisplayStyleObserver {
|
| +public class SelectableListLayout<E>
|
| + extends RelativeLayout implements DisplayStyleObserver, SelectionObserver<E> {
|
| + /**
|
| + * @param res Resources used to retrieve drawables and dimensions.
|
| + * @return The default list item lateral margin size in pixels. This value should be used in
|
| + * {@link HorizontalDisplayStyle#REGULAR} to hide the lateral shadow and rounded edges
|
| + * on items that use the list_item* 9-patches as a background.
|
| + */
|
| + public static int getDefaultListItemLateralMarginPx(Resources res) {
|
| + if (sDefaultListItemLateralMarginPx == -1) {
|
| + Rect listItemShadow = new Rect();
|
| + ApiCompatibilityUtils.getDrawable(res, R.drawable.card_middle)
|
| + .getPadding(listItemShadow);
|
| + int cardCornerRadius = res.getDimensionPixelSize(R.dimen.list_item_corner_radius);
|
| +
|
| + assert listItemShadow.left == listItemShadow.right;
|
| +
|
| + // A negative margin is used in HorizontalDisplayStyle#REGULAR to hide the lateral
|
| + // shadow.
|
| + sDefaultListItemLateralMarginPx = -(listItemShadow.left + cardCornerRadius);
|
| + }
|
| +
|
| + return sDefaultListItemLateralMarginPx;
|
| + }
|
| +
|
| private static final int WIDE_DISPLAY_MIN_PADDING_DP = 16;
|
|
|
| + private static int sDefaultListItemLateralMarginPx = -1;
|
| +
|
| private Adapter<RecyclerView.ViewHolder> mAdapter;
|
| private ViewStub mToolbarStub;
|
| private TextView mEmptyView;
|
| private LoadingView mLoadingView;
|
| private RecyclerView mRecyclerView;
|
| + private ItemAnimator mItemAnimator;
|
| SelectableListToolbar<E> mToolbar;
|
| + private FadingShadowView mToolbarShadow;
|
| +
|
| + private boolean mToolbarPermanentlyHidden;
|
| + private int mEmptyStringResId;
|
| + private int mSearchEmptyStringResId;
|
|
|
| private UiConfig mUiConfig;
|
|
|
| @@ -86,14 +125,6 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| }
|
| };
|
|
|
| - /**
|
| - * Unlike ListView or GridView, RecyclerView does not provide default empty
|
| - * view implementation. We need to check it ourselves.
|
| - */
|
| - private void updateEmptyViewVisibility() {
|
| - mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
| - }
|
| -
|
| public SelectableListLayout(Context context, AttributeSet attrs) {
|
| super(context, attrs);
|
| }
|
| @@ -135,7 +166,16 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
|
| mRecyclerView.setAdapter(mAdapter);
|
| mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
| +
|
| mRecyclerView.setHasFixedSize(true);
|
| + mRecyclerView.addOnScrollListener(new OnScrollListener() {
|
| + @Override
|
| + public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
|
| + setToolbarShadowVisibility();
|
| + }
|
| + });
|
| +
|
| + mItemAnimator = mRecyclerView.getItemAnimator();
|
|
|
| return mRecyclerView;
|
| }
|
| @@ -165,14 +205,6 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| int normalGroupResId, int selectedGroupResId,
|
| @Nullable Integer normalBackgroundColorResId, boolean hideShadowOnLargeTablets,
|
| @Nullable OnMenuItemClickListener listener) {
|
| - FadingShadowView shadow = (FadingShadowView) findViewById(R.id.shadow);
|
| - if (hideShadowOnLargeTablets && DeviceFormFactor.isLargeTablet(getContext())) {
|
| - shadow.setVisibility(View.GONE);
|
| - } else {
|
| - shadow.init(ApiCompatibilityUtils.getColor(getResources(),
|
| - R.color.toolbar_shadow_color), FadingShadow.POSITION_TOP);
|
| - }
|
| -
|
| mToolbarStub.setLayoutResource(toolbarLayoutId);
|
| @SuppressWarnings("unchecked")
|
| SelectableListToolbar<E> toolbar = (SelectableListToolbar<E>) mToolbarStub.inflate();
|
| @@ -184,6 +216,18 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| mToolbar.setOnMenuItemClickListener(listener);
|
| }
|
|
|
| + mToolbarShadow = (FadingShadowView) findViewById(R.id.shadow);
|
| + if (hideShadowOnLargeTablets && DeviceFormFactor.isLargeTablet(getContext())) {
|
| + mToolbarPermanentlyHidden = true;
|
| + mToolbarShadow.setVisibility(View.GONE);
|
| + } else {
|
| + mToolbarShadow.init(
|
| + ApiCompatibilityUtils.getColor(getResources(), R.color.toolbar_shadow_color),
|
| + FadingShadow.POSITION_TOP);
|
| + delegate.addObserver(this);
|
| + setToolbarShadowVisibility();
|
| + }
|
| +
|
| return mToolbar;
|
| }
|
|
|
| @@ -192,26 +236,26 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| *
|
| * @param emptyDrawable The Drawable to show when the selectable list is empty.
|
| * @param emptyStringResId The string to show when the selectable list is empty.
|
| + * @param searchEmptyStringResId The string to show when the selectable list is empty during
|
| + * a search.
|
| * @return The {@link TextView} displayed when the list is empty.
|
| */
|
| - public TextView initializeEmptyView(Drawable emptyDrawable, int emptyStringResId) {
|
| + public TextView initializeEmptyView(
|
| + Drawable emptyDrawable, int emptyStringResId, int searchEmptyStringResId) {
|
| + mEmptyStringResId = emptyStringResId;
|
| + mSearchEmptyStringResId = searchEmptyStringResId;
|
| +
|
| mEmptyView.setCompoundDrawablesWithIntrinsicBounds(null, emptyDrawable, null, null);
|
| - mEmptyView.setText(emptyStringResId);
|
| + mEmptyView.setText(mEmptyStringResId);
|
| return mEmptyView;
|
| }
|
|
|
| /**
|
| - * @param emptyStringResId The string to show when the selectable list is empty.
|
| - */
|
| - public void setEmptyViewText(int emptyStringResId) {
|
| - mEmptyView.setText(emptyStringResId);
|
| - }
|
| -
|
| - /**
|
| * Called when the view that owns the SelectableListLayout is destroyed.
|
| */
|
| public void onDestroyed() {
|
| mAdapter.unregisterAdapterDataObserver(mAdapterObserver);
|
| + mToolbar.getSelectionDelegate().removeObserver(this);
|
| }
|
|
|
| /**
|
| @@ -248,6 +292,29 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| padding, mRecyclerView.getPaddingBottom());
|
| }
|
|
|
| + @Override
|
| + public void onSelectionStateChange(List<E> selectedItems) {
|
| + setToolbarShadowVisibility();
|
| + }
|
| +
|
| + /**
|
| + * Called when a search is starting.
|
| + */
|
| + public void onStartSearch() {
|
| + mRecyclerView.setItemAnimator(null);
|
| + mToolbarShadow.setVisibility(View.VISIBLE);
|
| + mEmptyView.setText(mSearchEmptyStringResId);
|
| + }
|
| +
|
| + /**
|
| + * Called when a search has ended.
|
| + */
|
| + public void onEndSearch() {
|
| + mRecyclerView.setItemAnimator(mItemAnimator);
|
| + setToolbarShadowVisibility();
|
| + mEmptyView.setText(mEmptyStringResId);
|
| + }
|
| +
|
| /**
|
| * @param displayStyle The current display style..
|
| * @param resources The {@link Resources} used to retrieve configuration and display metrics.
|
| @@ -264,4 +331,25 @@ public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt
|
| }
|
| return padding;
|
| }
|
| +
|
| + private void setToolbarShadowVisibility() {
|
| + if (mToolbarPermanentlyHidden || mToolbar == null || mRecyclerView == null) return;
|
| +
|
| + boolean showShadow = mRecyclerView.computeVerticalScrollOffset() != 0
|
| + || mToolbar.isSearching() || mToolbar.getSelectionDelegate().isSelectionEnabled();
|
| + mToolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE);
|
| + }
|
| +
|
| + /**
|
| + * Unlike ListView or GridView, RecyclerView does not provide default empty
|
| + * view implementation. We need to check it ourselves.
|
| + */
|
| + private void updateEmptyViewVisibility() {
|
| + mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : View.GONE);
|
| + }
|
| +
|
| + @VisibleForTesting
|
| + public View getToolbarShadowForTests() {
|
| + return mToolbarShadow;
|
| + }
|
| }
|
|
|