| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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.widget.selection; | 5 package org.chromium.chrome.browser.widget.selection; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.content.res.Configuration; | 8 import android.content.res.Configuration; |
| 9 import android.content.res.Resources; | 9 import android.content.res.Resources; |
| 10 import android.graphics.Rect; | 10 import android.graphics.Rect; |
| 11 import android.graphics.drawable.Drawable; | 11 import android.graphics.drawable.Drawable; |
| 12 import android.support.annotation.VisibleForTesting; | 12 import android.support.annotation.VisibleForTesting; |
| 13 import android.support.v4.widget.DrawerLayout; | 13 import android.support.v4.widget.DrawerLayout; |
| 14 import android.support.v7.widget.LinearLayoutManager; | 14 import android.support.v7.widget.LinearLayoutManager; |
| 15 import android.support.v7.widget.RecyclerView; | 15 import android.support.v7.widget.RecyclerView; |
| 16 import android.support.v7.widget.RecyclerView.Adapter; | 16 import android.support.v7.widget.RecyclerView.Adapter; |
| 17 import android.support.v7.widget.RecyclerView.AdapterDataObserver; | 17 import android.support.v7.widget.RecyclerView.AdapterDataObserver; |
| 18 import android.support.v7.widget.RecyclerView.ItemAnimator; | 18 import android.support.v7.widget.RecyclerView.ItemAnimator; |
| 19 import android.support.v7.widget.RecyclerView.OnScrollListener; | 19 import android.support.v7.widget.RecyclerView.OnScrollListener; |
| 20 import android.support.v7.widget.Toolbar; | 20 import android.support.v7.widget.Toolbar; |
| 21 import android.support.v7.widget.Toolbar.OnMenuItemClickListener; | 21 import android.support.v7.widget.Toolbar.OnMenuItemClickListener; |
| 22 import android.util.AttributeSet; | 22 import android.util.AttributeSet; |
| 23 import android.view.Gravity; | 23 import android.view.Gravity; |
| 24 import android.view.LayoutInflater; | 24 import android.view.LayoutInflater; |
| 25 import android.view.View; | 25 import android.view.View; |
| 26 import android.view.ViewStub; | 26 import android.view.ViewStub; |
| 27 import android.widget.FrameLayout; | 27 import android.widget.FrameLayout; |
| 28 import android.widget.RelativeLayout; | |
| 29 import android.widget.TextView; | 28 import android.widget.TextView; |
| 30 | 29 |
| 31 import org.chromium.base.ApiCompatibilityUtils; | 30 import org.chromium.base.ApiCompatibilityUtils; |
| 32 import org.chromium.chrome.R; | 31 import org.chromium.chrome.R; |
| 33 import org.chromium.chrome.browser.util.FeatureUtilities; | 32 import org.chromium.chrome.browser.util.FeatureUtilities; |
| 34 import org.chromium.chrome.browser.widget.FadingShadow; | 33 import org.chromium.chrome.browser.widget.FadingShadow; |
| 35 import org.chromium.chrome.browser.widget.FadingShadowView; | 34 import org.chromium.chrome.browser.widget.FadingShadowView; |
| 36 import org.chromium.chrome.browser.widget.LoadingView; | 35 import org.chromium.chrome.browser.widget.LoadingView; |
| 37 import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; | 36 import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; |
| 38 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; | 37 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; |
| 39 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; | 38 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; |
| 40 import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle; | 39 import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle; |
| 41 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionO
bserver; | 40 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionO
bserver; |
| 42 import org.chromium.ui.base.DeviceFormFactor; | 41 import org.chromium.ui.base.DeviceFormFactor; |
| 43 | 42 |
| 44 import java.util.List; | 43 import java.util.List; |
| 45 | 44 |
| 46 import javax.annotation.Nullable; | 45 import javax.annotation.Nullable; |
| 47 | 46 |
| 48 /** | 47 /** |
| 49 * Contains UI elements common to selectable list views: a loading view, empty v
iew, selection | 48 * Contains UI elements common to selectable list views: a loading view, empty v
iew, selection |
| 50 * toolbar, shadow, and RecyclerView. | 49 * toolbar, shadow, and RecyclerView. |
| 51 * | 50 * |
| 52 * After the SelectableListLayout is inflated, it should be initialized through
calls to | 51 * After the SelectableListLayout is inflated, it should be initialized through
calls to |
| 53 * #initializeRecyclerView(), #initializeToolbar(), and #initializeEmptyView(). | 52 * #initializeRecyclerView(), #initializeToolbar(), and #initializeEmptyView(). |
| 54 * | 53 * |
| 55 * @param <E> The type of the selectable items this layout holds. | 54 * @param <E> The type of the selectable items this layout holds. |
| 56 */ | 55 */ |
| 57 public class SelectableListLayout<E> | 56 public class SelectableListLayout<E> |
| 58 extends RelativeLayout implements DisplayStyleObserver, SelectionObserve
r<E> { | 57 extends FrameLayout implements DisplayStyleObserver, SelectionObserver<E
> { |
| 59 /** | 58 /** |
| 60 * @param res Resources used to retrieve drawables and dimensions. | 59 * @param res Resources used to retrieve drawables and dimensions. |
| 61 * @return The default list item lateral margin size in pixels. This value s
hould be used in | 60 * @return The default list item lateral margin size in pixels. This value s
hould be used in |
| 62 * {@link HorizontalDisplayStyle#REGULAR} to hide the lateral shadow
and rounded edges | 61 * {@link HorizontalDisplayStyle#REGULAR} to hide the lateral shadow
and rounded edges |
| 63 * on items that use the list_item* 9-patches as a background. | 62 * on items that use the list_item* 9-patches as a background. |
| 64 */ | 63 */ |
| 65 public static int getDefaultListItemLateralMarginPx(Resources res) { | 64 public static int getDefaultListItemLateralMarginPx(Resources res) { |
| 66 if (sDefaultListItemLateralMarginPx == -1) { | 65 if (sDefaultListItemLateralMarginPx == -1) { |
| 67 Rect listItemShadow = new Rect(); | 66 Rect listItemShadow = new Rect(); |
| 68 ApiCompatibilityUtils.getDrawable(res, R.drawable.card_middle) | 67 ApiCompatibilityUtils.getDrawable(res, R.drawable.card_middle) |
| (...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 setToolbarShadowVisibility(); | 310 setToolbarShadowVisibility(); |
| 312 } | 311 } |
| 313 | 312 |
| 314 /** | 313 /** |
| 315 * Removes the toolbar view from this view and returns it so that it may be
re-attached | 314 * Removes the toolbar view from this view and returns it so that it may be
re-attached |
| 316 * elsewhere. | 315 * elsewhere. |
| 317 * @return The toolbar view. | 316 * @return The toolbar view. |
| 318 */ | 317 */ |
| 319 public Toolbar detachToolbarView() { | 318 public Toolbar detachToolbarView() { |
| 320 removeView(mToolbar); | 319 removeView(mToolbar); |
| 320 |
| 321 // The top margin for the content and shadow needs to be removed now tha
t the toolbar |
| 322 // has been removed. |
| 323 View content = findViewById(R.id.list_content); |
| 324 ((MarginLayoutParams) content.getLayoutParams()).topMargin = 0; |
| 325 ((MarginLayoutParams) mToolbarShadow.getLayoutParams()).topMargin = 0; |
| 326 |
| 321 return mToolbar; | 327 return mToolbar; |
| 322 } | 328 } |
| 323 | 329 |
| 324 /** | 330 /** |
| 325 * Called when a search is starting. | 331 * Called when a search is starting. |
| 326 */ | 332 */ |
| 327 public void onStartSearch() { | 333 public void onStartSearch() { |
| 328 mRecyclerView.setItemAnimator(null); | 334 mRecyclerView.setItemAnimator(null); |
| 329 mToolbarShadow.setVisibility(View.VISIBLE); | 335 mToolbarShadow.setVisibility(View.VISIBLE); |
| 330 mEmptyView.setText(mSearchEmptyStringResId); | 336 mEmptyView.setText(mSearchEmptyStringResId); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 352 padding = (int) (((screenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_W
IDTH_DP) / 2.f) | 358 padding = (int) (((screenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_W
IDTH_DP) / 2.f) |
| 353 * dpToPx); | 359 * dpToPx); |
| 354 padding = (int) Math.max(WIDE_DISPLAY_MIN_PADDING_DP * dpToPx, paddi
ng); | 360 padding = (int) Math.max(WIDE_DISPLAY_MIN_PADDING_DP * dpToPx, paddi
ng); |
| 355 } | 361 } |
| 356 return padding; | 362 return padding; |
| 357 } | 363 } |
| 358 | 364 |
| 359 private void setToolbarShadowVisibility() { | 365 private void setToolbarShadowVisibility() { |
| 360 if (mToolbarPermanentlyHidden || mToolbar == null || mRecyclerView == nu
ll) return; | 366 if (mToolbarPermanentlyHidden || mToolbar == null || mRecyclerView == nu
ll) return; |
| 361 | 367 |
| 362 boolean showShadow = mRecyclerView.computeVerticalScrollOffset() != 0 | 368 boolean showShadow = mRecyclerView.canScrollVertically(-1) || mToolbar.i
sSearching() |
| 363 || mToolbar.isSearching() || mToolbar.getSelectionDelegate().isS
electionEnabled(); | 369 || mToolbar.getSelectionDelegate().isSelectionEnabled(); |
| 364 mToolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE); | 370 mToolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE); |
| 365 } | 371 } |
| 366 | 372 |
| 367 /** | 373 /** |
| 368 * Unlike ListView or GridView, RecyclerView does not provide default empty | 374 * Unlike ListView or GridView, RecyclerView does not provide default empty |
| 369 * view implementation. We need to check it ourselves. | 375 * view implementation. We need to check it ourselves. |
| 370 */ | 376 */ |
| 371 private void updateEmptyViewVisibility() { | 377 private void updateEmptyViewVisibility() { |
| 372 mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : V
iew.GONE); | 378 mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : V
iew.GONE); |
| 373 } | 379 } |
| 374 | 380 |
| 375 @VisibleForTesting | 381 @VisibleForTesting |
| 376 public View getToolbarShadowForTests() { | 382 public View getToolbarShadowForTests() { |
| 377 return mToolbarShadow; | 383 return mToolbarShadow; |
| 378 } | 384 } |
| 379 | 385 |
| 380 private void setEmptyOrLoadingViewStyle(View view) { | 386 private void setEmptyOrLoadingViewStyle(View view) { |
| 381 if (!FeatureUtilities.isChromeHomeEnabled()) return; | 387 if (!FeatureUtilities.isChromeHomeEnabled()) return; |
| 382 | 388 |
| 383 ((FrameLayout.LayoutParams) view.getLayoutParams()).gravity = Gravity.CE
NTER_HORIZONTAL; | 389 ((FrameLayout.LayoutParams) view.getLayoutParams()).gravity = Gravity.CE
NTER_HORIZONTAL; |
| 384 ApiCompatibilityUtils.setPaddingRelative(view, ApiCompatibilityUtils.get
PaddingStart(view), | 390 ApiCompatibilityUtils.setPaddingRelative(view, ApiCompatibilityUtils.get
PaddingStart(view), |
| 385 view.getPaddingTop() + mChromeHomeEmptyAndLoadingViewTopPadding, | 391 view.getPaddingTop() + mChromeHomeEmptyAndLoadingViewTopPadding, |
| 386 ApiCompatibilityUtils.getPaddingEnd(view), view.getPaddingBottom
()); | 392 ApiCompatibilityUtils.getPaddingEnd(view), view.getPaddingBottom
()); |
| 387 } | 393 } |
| 388 } | 394 } |
| OLD | NEW |