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.drawable.Drawable; | 11 import android.graphics.drawable.Drawable; |
12 import android.support.annotation.VisibleForTesting; | |
11 import android.support.v4.widget.DrawerLayout; | 13 import android.support.v4.widget.DrawerLayout; |
12 import android.support.v7.widget.LinearLayoutManager; | 14 import android.support.v7.widget.LinearLayoutManager; |
13 import android.support.v7.widget.RecyclerView; | 15 import android.support.v7.widget.RecyclerView; |
14 import android.support.v7.widget.RecyclerView.Adapter; | 16 import android.support.v7.widget.RecyclerView.Adapter; |
15 import android.support.v7.widget.RecyclerView.AdapterDataObserver; | 17 import android.support.v7.widget.RecyclerView.AdapterDataObserver; |
18 import android.support.v7.widget.RecyclerView.ItemAnimator; | |
19 import android.support.v7.widget.RecyclerView.OnScrollListener; | |
16 import android.support.v7.widget.Toolbar.OnMenuItemClickListener; | 20 import android.support.v7.widget.Toolbar.OnMenuItemClickListener; |
17 import android.util.AttributeSet; | 21 import android.util.AttributeSet; |
18 import android.view.LayoutInflater; | 22 import android.view.LayoutInflater; |
19 import android.view.View; | 23 import android.view.View; |
20 import android.view.ViewStub; | 24 import android.view.ViewStub; |
21 import android.widget.RelativeLayout; | 25 import android.widget.RelativeLayout; |
22 import android.widget.TextView; | 26 import android.widget.TextView; |
23 | 27 |
24 import org.chromium.base.ApiCompatibilityUtils; | 28 import org.chromium.base.ApiCompatibilityUtils; |
25 import org.chromium.chrome.R; | 29 import org.chromium.chrome.R; |
26 import org.chromium.chrome.browser.widget.FadingShadow; | 30 import org.chromium.chrome.browser.widget.FadingShadow; |
27 import org.chromium.chrome.browser.widget.FadingShadowView; | 31 import org.chromium.chrome.browser.widget.FadingShadowView; |
28 import org.chromium.chrome.browser.widget.LoadingView; | 32 import org.chromium.chrome.browser.widget.LoadingView; |
29 import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; | 33 import org.chromium.chrome.browser.widget.displaystyle.DisplayStyleObserver; |
30 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; | 34 import org.chromium.chrome.browser.widget.displaystyle.HorizontalDisplayStyle; |
31 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; | 35 import org.chromium.chrome.browser.widget.displaystyle.UiConfig; |
32 import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle; | 36 import org.chromium.chrome.browser.widget.displaystyle.UiConfig.DisplayStyle; |
37 import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionO bserver; | |
33 import org.chromium.ui.base.DeviceFormFactor; | 38 import org.chromium.ui.base.DeviceFormFactor; |
34 | 39 |
40 import java.util.List; | |
41 | |
35 import javax.annotation.Nullable; | 42 import javax.annotation.Nullable; |
36 | 43 |
37 /** | 44 /** |
38 * Contains UI elements common to selectable list views: a loading view, empty v iew, selection | 45 * Contains UI elements common to selectable list views: a loading view, empty v iew, selection |
39 * toolbar, shadow, and RecyclerView. | 46 * toolbar, shadow, and RecyclerView. |
40 * | 47 * |
41 * After the SelectableListLayout is inflated, it should be initialized through calls to | 48 * After the SelectableListLayout is inflated, it should be initialized through calls to |
42 * #initializeRecyclerView(), #initializeToolbar(), and #initializeEmptyView(). | 49 * #initializeRecyclerView(), #initializeToolbar(), and #initializeEmptyView(). |
43 * | 50 * |
44 * @param <E> The type of the selectable items this layout holds. | 51 * @param <E> The type of the selectable items this layout holds. |
45 */ | 52 */ |
46 public class SelectableListLayout<E> extends RelativeLayout implements DisplaySt yleObserver { | 53 public class SelectableListLayout<E> |
54 extends RelativeLayout implements DisplayStyleObserver, SelectionObserve r<E> { | |
55 /** | |
56 * @param res Resources used to retrieve drawables and dimensions. | |
57 * @return The default list item lateral margin size in pixels. This value s hould be used in | |
58 * {@link HorizontalDisplayStyle#REGULAR} to hide the lateral shadow and rounded edges | |
59 * on items that use the list_item* 9-patches as a background. | |
60 */ | |
61 public static int getDefaultListItemLateralMarginPx(Resources res) { | |
62 if (sDefaultListItemLateralMarginPx == null) { | |
63 Rect listItemShadow = new Rect(); | |
64 ApiCompatibilityUtils.getDrawable(res, R.drawable.card_middle) | |
65 .getPadding(listItemShadow); | |
66 int cardCornerRadius = res.getDimensionPixelSize(R.dimen.list_item_c orner_radius); | |
67 | |
68 assert listItemShadow.left == listItemShadow.right; | |
69 // A negative margin is used in HorizontalDisplayStyle#REGULAR to hi de the lateral | |
70 // shadow. | |
gone
2017/02/17 01:45:02
Swap assert and comment to avoid comment sandwich,
Theresa
2017/02/17 17:34:28
I added an extra blank line between the assert and
gone
2017/02/17 17:57:51
My sensibilities thank you.
| |
71 sDefaultListItemLateralMarginPx = -(listItemShadow.left + cardCorner Radius); | |
72 } | |
73 | |
74 return sDefaultListItemLateralMarginPx; | |
75 } | |
76 | |
47 private static final int WIDE_DISPLAY_MIN_PADDING_DP = 16; | 77 private static final int WIDE_DISPLAY_MIN_PADDING_DP = 16; |
48 | 78 |
79 private static Integer sDefaultListItemLateralMarginPx; | |
gone
2017/02/17 01:45:02
maybe use a regular int and -1?
Theresa
2017/02/17 17:34:28
Done.
| |
80 | |
49 private Adapter<RecyclerView.ViewHolder> mAdapter; | 81 private Adapter<RecyclerView.ViewHolder> mAdapter; |
50 private ViewStub mToolbarStub; | 82 private ViewStub mToolbarStub; |
51 private TextView mEmptyView; | 83 private TextView mEmptyView; |
52 private LoadingView mLoadingView; | 84 private LoadingView mLoadingView; |
53 private RecyclerView mRecyclerView; | 85 private RecyclerView mRecyclerView; |
86 private ItemAnimator mItemAnimator; | |
54 SelectableListToolbar<E> mToolbar; | 87 SelectableListToolbar<E> mToolbar; |
88 private FadingShadowView mToolbarShadow; | |
89 | |
90 private boolean mToolbarPermanentlyHidden; | |
91 private int mEmptyStringResId; | |
92 private int mSearchEmptyStringResId; | |
55 | 93 |
56 private UiConfig mUiConfig; | 94 private UiConfig mUiConfig; |
57 | 95 |
58 private final AdapterDataObserver mAdapterObserver = new AdapterDataObserver () { | 96 private final AdapterDataObserver mAdapterObserver = new AdapterDataObserver () { |
59 @Override | 97 @Override |
60 public void onChanged() { | 98 public void onChanged() { |
61 super.onChanged(); | 99 super.onChanged(); |
62 if (mAdapter.getItemCount() == 0) { | 100 if (mAdapter.getItemCount() == 0) { |
63 mEmptyView.setVisibility(View.VISIBLE); | 101 mEmptyView.setVisibility(View.VISIBLE); |
64 mRecyclerView.setVisibility(View.GONE); | 102 mRecyclerView.setVisibility(View.GONE); |
(...skipping 14 matching lines...) Expand all Loading... | |
79 updateEmptyViewVisibility(); | 117 updateEmptyViewVisibility(); |
80 } | 118 } |
81 | 119 |
82 @Override | 120 @Override |
83 public void onItemRangeRemoved(int positionStart, int itemCount) { | 121 public void onItemRangeRemoved(int positionStart, int itemCount) { |
84 super.onItemRangeRemoved(positionStart, itemCount); | 122 super.onItemRangeRemoved(positionStart, itemCount); |
85 updateEmptyViewVisibility(); | 123 updateEmptyViewVisibility(); |
86 } | 124 } |
87 }; | 125 }; |
88 | 126 |
89 /** | |
90 * Unlike ListView or GridView, RecyclerView does not provide default empty | |
91 * view implementation. We need to check it ourselves. | |
92 */ | |
93 private void updateEmptyViewVisibility() { | |
94 mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : V iew.GONE); | |
95 } | |
96 | |
97 public SelectableListLayout(Context context, AttributeSet attrs) { | 127 public SelectableListLayout(Context context, AttributeSet attrs) { |
98 super(context, attrs); | 128 super(context, attrs); |
99 } | 129 } |
100 | 130 |
101 @Override | 131 @Override |
102 protected void onFinishInflate() { | 132 protected void onFinishInflate() { |
103 super.onFinishInflate(); | 133 super.onFinishInflate(); |
104 | 134 |
105 LayoutInflater.from(getContext()).inflate(R.layout.selectable_list_layou t, this); | 135 LayoutInflater.from(getContext()).inflate(R.layout.selectable_list_layou t, this); |
106 | 136 |
(...skipping 21 matching lines...) Expand all Loading... | |
128 * that are displayed within the RecyclerView. | 158 * that are displayed within the RecyclerView. |
129 * @return The RecyclerView itself. | 159 * @return The RecyclerView itself. |
130 */ | 160 */ |
131 public RecyclerView initializeRecyclerView(Adapter<RecyclerView.ViewHolder> adapter) { | 161 public RecyclerView initializeRecyclerView(Adapter<RecyclerView.ViewHolder> adapter) { |
132 mAdapter = adapter; | 162 mAdapter = adapter; |
133 mAdapter.registerAdapterDataObserver(mAdapterObserver); | 163 mAdapter.registerAdapterDataObserver(mAdapterObserver); |
134 | 164 |
135 mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); | 165 mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view); |
136 mRecyclerView.setAdapter(mAdapter); | 166 mRecyclerView.setAdapter(mAdapter); |
137 mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); | 167 mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); |
168 | |
138 mRecyclerView.setHasFixedSize(true); | 169 mRecyclerView.setHasFixedSize(true); |
170 mRecyclerView.addOnScrollListener(new OnScrollListener() { | |
171 @Override | |
172 public void onScrolled(RecyclerView recyclerView, int dx, int dy) { | |
173 setToolbarShadowVisibility(); | |
174 } | |
175 }); | |
176 | |
177 mItemAnimator = mRecyclerView.getItemAnimator(); | |
139 | 178 |
140 return mRecyclerView; | 179 return mRecyclerView; |
141 } | 180 } |
142 | 181 |
143 /** | 182 /** |
144 * Initializes the SelectionToolbar. | 183 * Initializes the SelectionToolbar. |
145 * | 184 * |
146 * @param toolbarLayoutId The resource id of the toolbar layout. This will b e inflated into | 185 * @param toolbarLayoutId The resource id of the toolbar layout. This will b e inflated into |
147 * a ViewStub. | 186 * a ViewStub. |
148 * @param delegate The SelectionDelegate that will inform the toolbar of sel ection changes. | 187 * @param delegate The SelectionDelegate that will inform the toolbar of sel ection changes. |
149 * @param titleResId The resource id of the title string. May be 0 if this c lass shouldn't set | 188 * @param titleResId The resource id of the title string. May be 0 if this c lass shouldn't set |
150 * set a title when the selection is cleared. | 189 * set a title when the selection is cleared. |
151 * @param drawerLayout The DrawerLayout whose navigation icon is displayed i n this toolbar. | 190 * @param drawerLayout The DrawerLayout whose navigation icon is displayed i n this toolbar. |
152 * @param normalGroupResId The resource id of the menu group to show when a selection isn't | 191 * @param normalGroupResId The resource id of the menu group to show when a selection isn't |
153 * established. | 192 * established. |
154 * @param selectedGroupResId The resource id of the menu item to show when a selection is | 193 * @param selectedGroupResId The resource id of the menu item to show when a selection is |
155 * established. | 194 * established. |
156 * @param normalBackgroundColorResId The resource id of the color to use as the background color | 195 * @param normalBackgroundColorResId The resource id of the color to use as the background color |
157 * when selection is not enabled. If null the default appbar | 196 * when selection is not enabled. If null the default appbar |
158 * background color will be used. | 197 * background color will be used. |
159 * @param hideShadowOnLargeTablets Whether the toolbar shadow should be hidd en on large tablets. | 198 * @param hideShadowOnLargeTablets Whether the toolbar shadow should be hidd en on large tablets. |
160 * @param listener The OnMenuItemClickListener to set on the toolbar. | 199 * @param listener The OnMenuItemClickListener to set on the toolbar. |
161 * @return The initialized SelectionToolbar. | 200 * @return The initialized SelectionToolbar. |
162 */ | 201 */ |
163 public SelectableListToolbar<E> initializeToolbar(int toolbarLayoutId, | 202 public SelectableListToolbar<E> initializeToolbar(int toolbarLayoutId, |
164 SelectionDelegate<E> delegate, int titleResId, @Nullable DrawerLayou t drawerLayout, | 203 SelectionDelegate<E> delegate, int titleResId, @Nullable DrawerLayou t drawerLayout, |
165 int normalGroupResId, int selectedGroupResId, | 204 int normalGroupResId, int selectedGroupResId, |
166 @Nullable Integer normalBackgroundColorResId, boolean hideShadowOnLa rgeTablets, | 205 @Nullable Integer normalBackgroundColorResId, boolean hideShadowOnLa rgeTablets, |
167 @Nullable OnMenuItemClickListener listener) { | 206 @Nullable OnMenuItemClickListener listener) { |
168 FadingShadowView shadow = (FadingShadowView) findViewById(R.id.shadow); | |
169 if (hideShadowOnLargeTablets && DeviceFormFactor.isLargeTablet(getContex t())) { | |
170 shadow.setVisibility(View.GONE); | |
171 } else { | |
172 shadow.init(ApiCompatibilityUtils.getColor(getResources(), | |
173 R.color.toolbar_shadow_color), FadingShadow.POSITION_TOP); | |
174 } | |
175 | |
176 mToolbarStub.setLayoutResource(toolbarLayoutId); | 207 mToolbarStub.setLayoutResource(toolbarLayoutId); |
177 @SuppressWarnings("unchecked") | 208 @SuppressWarnings("unchecked") |
178 SelectableListToolbar<E> toolbar = (SelectableListToolbar<E>) mToolbarSt ub.inflate(); | 209 SelectableListToolbar<E> toolbar = (SelectableListToolbar<E>) mToolbarSt ub.inflate(); |
179 mToolbar = toolbar; | 210 mToolbar = toolbar; |
180 mToolbar.initialize(delegate, titleResId, drawerLayout, normalGroupResId , | 211 mToolbar.initialize(delegate, titleResId, drawerLayout, normalGroupResId , |
181 selectedGroupResId, normalBackgroundColorResId); | 212 selectedGroupResId, normalBackgroundColorResId); |
182 | 213 |
183 if (listener != null) { | 214 if (listener != null) { |
184 mToolbar.setOnMenuItemClickListener(listener); | 215 mToolbar.setOnMenuItemClickListener(listener); |
185 } | 216 } |
186 | 217 |
218 mToolbarShadow = (FadingShadowView) findViewById(R.id.shadow); | |
219 if (hideShadowOnLargeTablets && DeviceFormFactor.isLargeTablet(getContex t())) { | |
220 mToolbarPermanentlyHidden = true; | |
221 mToolbarShadow.setVisibility(View.GONE); | |
222 } else { | |
223 mToolbarShadow.init( | |
224 ApiCompatibilityUtils.getColor(getResources(), R.color.toolb ar_shadow_color), | |
225 FadingShadow.POSITION_TOP); | |
226 delegate.addObserver(this); | |
227 setToolbarShadowVisibility(); | |
228 } | |
229 | |
187 return mToolbar; | 230 return mToolbar; |
188 } | 231 } |
189 | 232 |
190 /** | 233 /** |
191 * Initializes the view shown when the selectable list is empty. | 234 * Initializes the view shown when the selectable list is empty. |
192 * | 235 * |
193 * @param emptyDrawable The Drawable to show when the selectable list is emp ty. | 236 * @param emptyDrawable The Drawable to show when the selectable list is emp ty. |
194 * @param emptyStringResId The string to show when the selectable list is em pty. | 237 * @param emptyStringResId The string to show when the selectable list is em pty. |
238 * @param searchEmptyStringResId The string to show when the selectable list is empty during | |
239 * a search. | |
195 * @return The {@link TextView} displayed when the list is empty. | 240 * @return The {@link TextView} displayed when the list is empty. |
196 */ | 241 */ |
197 public TextView initializeEmptyView(Drawable emptyDrawable, int emptyStringR esId) { | 242 public TextView initializeEmptyView( |
243 Drawable emptyDrawable, int emptyStringResId, int searchEmptyStringR esId) { | |
244 mEmptyStringResId = emptyStringResId; | |
245 mSearchEmptyStringResId = searchEmptyStringResId; | |
246 | |
198 mEmptyView.setCompoundDrawablesWithIntrinsicBounds(null, emptyDrawable, null, null); | 247 mEmptyView.setCompoundDrawablesWithIntrinsicBounds(null, emptyDrawable, null, null); |
199 mEmptyView.setText(emptyStringResId); | 248 mEmptyView.setText(mEmptyStringResId); |
200 return mEmptyView; | 249 return mEmptyView; |
201 } | 250 } |
202 | 251 |
203 /** | 252 /** |
204 * @param emptyStringResId The string to show when the selectable list is em pty. | |
205 */ | |
206 public void setEmptyViewText(int emptyStringResId) { | |
207 mEmptyView.setText(emptyStringResId); | |
208 } | |
209 | |
210 /** | |
211 * Called when the view that owns the SelectableListLayout is destroyed. | 253 * Called when the view that owns the SelectableListLayout is destroyed. |
212 */ | 254 */ |
213 public void onDestroyed() { | 255 public void onDestroyed() { |
214 mAdapter.unregisterAdapterDataObserver(mAdapterObserver); | 256 mAdapter.unregisterAdapterDataObserver(mAdapterObserver); |
257 mToolbar.getSelectionDelegate().removeObserver(this); | |
215 } | 258 } |
216 | 259 |
217 /** | 260 /** |
218 * When this layout has a wide display style, it will be width constrained t o | 261 * When this layout has a wide display style, it will be width constrained t o |
219 * {@link UiConfig#WIDE_DISPLAY_STYLE_MIN_WIDTH_DP}. If the current screen w idth is greater than | 262 * {@link UiConfig#WIDE_DISPLAY_STYLE_MIN_WIDTH_DP}. If the current screen w idth is greater than |
220 * UiConfig#WIDE_DISPLAY_STYLE_MIN_WIDTH_DP, the SelectableListLayout will b e visually centered | 263 * UiConfig#WIDE_DISPLAY_STYLE_MIN_WIDTH_DP, the SelectableListLayout will b e visually centered |
221 * by adding padding to both sides. | 264 * by adding padding to both sides. |
222 * | 265 * |
223 * This method should be called after the toolbar and RecyclerView are initi alized. | 266 * This method should be called after the toolbar and RecyclerView are initi alized. |
224 * | 267 * |
(...skipping 16 matching lines...) Expand all Loading... | |
241 | 284 |
242 @Override | 285 @Override |
243 public void onDisplayStyleChanged(DisplayStyle newDisplayStyle) { | 286 public void onDisplayStyleChanged(DisplayStyle newDisplayStyle) { |
244 int padding = getPaddingForDisplayStyle(newDisplayStyle, getResources()) ; | 287 int padding = getPaddingForDisplayStyle(newDisplayStyle, getResources()) ; |
245 | 288 |
246 ApiCompatibilityUtils.setPaddingRelative(mRecyclerView, | 289 ApiCompatibilityUtils.setPaddingRelative(mRecyclerView, |
247 padding, mRecyclerView.getPaddingTop(), | 290 padding, mRecyclerView.getPaddingTop(), |
248 padding, mRecyclerView.getPaddingBottom()); | 291 padding, mRecyclerView.getPaddingBottom()); |
249 } | 292 } |
250 | 293 |
294 @Override | |
295 public void onSelectionStateChange(List<E> selectedItems) { | |
296 setToolbarShadowVisibility(); | |
297 } | |
298 | |
299 /** | |
300 * Called when a search is starting. | |
301 */ | |
302 public void onStartSearch() { | |
303 mRecyclerView.setItemAnimator(null); | |
304 mToolbarShadow.setVisibility(View.VISIBLE); | |
305 mEmptyView.setText(mSearchEmptyStringResId); | |
306 } | |
307 | |
308 /** | |
309 * Called when a search has ended. | |
310 */ | |
311 public void onEndSearch() { | |
312 mRecyclerView.setItemAnimator(mItemAnimator); | |
313 setToolbarShadowVisibility(); | |
314 mEmptyView.setText(mEmptyStringResId); | |
315 } | |
316 | |
251 /** | 317 /** |
252 * @param displayStyle The current display style.. | 318 * @param displayStyle The current display style.. |
253 * @param resources The {@link Resources} used to retrieve configuration and display metrics. | 319 * @param resources The {@link Resources} used to retrieve configuration and display metrics. |
254 * @return The lateral padding to use for the current display style. | 320 * @return The lateral padding to use for the current display style. |
255 */ | 321 */ |
256 public static int getPaddingForDisplayStyle(DisplayStyle displayStyle, Resou rces resources) { | 322 public static int getPaddingForDisplayStyle(DisplayStyle displayStyle, Resou rces resources) { |
257 int padding = 0; | 323 int padding = 0; |
258 if (displayStyle.horizontal == HorizontalDisplayStyle.WIDE) { | 324 if (displayStyle.horizontal == HorizontalDisplayStyle.WIDE) { |
259 int screenWidthDp = resources.getConfiguration().screenWidthDp; | 325 int screenWidthDp = resources.getConfiguration().screenWidthDp; |
260 float dpToPx = resources.getDisplayMetrics().density; | 326 float dpToPx = resources.getDisplayMetrics().density; |
261 padding = (int) (((screenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_W IDTH_DP) / 2.f) | 327 padding = (int) (((screenWidthDp - UiConfig.WIDE_DISPLAY_STYLE_MIN_W IDTH_DP) / 2.f) |
262 * dpToPx); | 328 * dpToPx); |
263 padding = (int) Math.max(WIDE_DISPLAY_MIN_PADDING_DP * dpToPx, paddi ng); | 329 padding = (int) Math.max(WIDE_DISPLAY_MIN_PADDING_DP * dpToPx, paddi ng); |
264 } | 330 } |
265 return padding; | 331 return padding; |
266 } | 332 } |
333 | |
334 private void setToolbarShadowVisibility() { | |
335 if (mToolbarPermanentlyHidden || mToolbar == null || mRecyclerView == nu ll) return; | |
336 | |
337 boolean showShadow = mRecyclerView.computeVerticalScrollOffset() != 0 | |
338 || mToolbar.isSearching() || mToolbar.getSelectionDelegate().isS electionEnabled(); | |
339 mToolbarShadow.setVisibility(showShadow ? View.VISIBLE : View.GONE); | |
340 } | |
341 | |
342 /** | |
343 * Unlike ListView or GridView, RecyclerView does not provide default empty | |
344 * view implementation. We need to check it ourselves. | |
345 */ | |
346 private void updateEmptyViewVisibility() { | |
347 mEmptyView.setVisibility(mAdapter.getItemCount() == 0 ? View.VISIBLE : V iew.GONE); | |
348 } | |
349 | |
350 @VisibleForTesting | |
351 public View getToolbarShadowForTests() { | |
352 return mToolbarShadow; | |
353 } | |
267 } | 354 } |
OLD | NEW |