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 |