OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.enhancedbookmarks; |
| 6 |
| 7 import android.content.Context; |
| 8 import android.graphics.Rect; |
| 9 import android.support.v7.widget.GridLayoutManager; |
| 10 import android.support.v7.widget.GridLayoutManager.SpanSizeLookup; |
| 11 import android.support.v7.widget.RecyclerView; |
| 12 import android.util.AttributeSet; |
| 13 import android.view.View; |
| 14 import android.widget.Checkable; |
| 15 import android.widget.RelativeLayout; |
| 16 |
| 17 import com.google.android.apps.chrome.R; |
| 18 |
| 19 import org.chromium.components.bookmarks.BookmarkId; |
| 20 |
| 21 import java.util.List; |
| 22 |
| 23 /** |
| 24 * Container for all bookmark items shown in enhanced bookmark manager. |
| 25 */ |
| 26 public class EnhancedBookmarkRecyclerView extends RecyclerView implements |
| 27 EnhancedBookmarkUIObserver { |
| 28 private static final int MINIMUM_LARGE_TABLET_WIDTH_DP = 720; |
| 29 private static Boolean sIsLargeTablet = null; |
| 30 |
| 31 private EnhancedBookmarkDelegate mDelegate; |
| 32 private View mEmptyView; |
| 33 private int mGridMinWidthPx; |
| 34 private int mItemHalfSpacePx; |
| 35 private ItemDecoration mItemDecoration; |
| 36 |
| 37 /** |
| 38 * @return True if the current device's minimum dimension is larger than 720
dp. |
| 39 */ |
| 40 public static boolean isLargeTablet(Context context) { |
| 41 // TODO(ianwen): move this function to DeviceFormFactor.java in upstream
. |
| 42 if (sIsLargeTablet == null) { |
| 43 int minimumScreenWidthDp = context.getResources().getConfiguration() |
| 44 .smallestScreenWidthDp; |
| 45 sIsLargeTablet = minimumScreenWidthDp >= MINIMUM_LARGE_TABLET_WIDTH_
DP; |
| 46 } |
| 47 return sIsLargeTablet; |
| 48 } |
| 49 |
| 50 /** |
| 51 * Constructs a new instance of enhanced bookmark recycler view. |
| 52 */ |
| 53 public EnhancedBookmarkRecyclerView(Context context, AttributeSet attrs) { |
| 54 super(context, attrs); |
| 55 // Span count will be dynamically computed in onMeasure(). |
| 56 setLayoutManager(new GridLayoutManager(context, 1)); |
| 57 mGridMinWidthPx = getResources().getDimensionPixelSize( |
| 58 R.dimen.enhanced_bookmark_min_grid_width); |
| 59 mItemHalfSpacePx = getResources().getDimensionPixelSize( |
| 60 R.dimen.enhanced_bookmark_item_half_space); |
| 61 mItemDecoration = new ItemDecoration() { |
| 62 @Override |
| 63 public void getItemOffsets(Rect outRect, View view, RecyclerView par
ent, State state) { |
| 64 outRect.set(mItemHalfSpacePx, mItemHalfSpacePx, mItemHalfSpacePx
, mItemHalfSpacePx); |
| 65 } |
| 66 }; |
| 67 setHasFixedSize(true); |
| 68 } |
| 69 |
| 70 @Override |
| 71 protected void onMeasure(int widthSpec, int heightSpec) { |
| 72 super.onMeasure(widthSpec, heightSpec); |
| 73 int width = MeasureSpec.getSize(widthSpec); |
| 74 if (width != 0 && mDelegate != null && !mDelegate.isListModeEnabled()) { |
| 75 int spans = width / mGridMinWidthPx; |
| 76 if (spans > 0) { |
| 77 getLayoutManager().setSpanCount(spans); |
| 78 if (getAdapter() != null) getAdapter().setNumColumns(spans); |
| 79 } |
| 80 } |
| 81 } |
| 82 |
| 83 /** |
| 84 * Sets the view to be shown if there are no items in adapter. |
| 85 */ |
| 86 public void setEmptyView(View emptyView) { |
| 87 mEmptyView = emptyView; |
| 88 } |
| 89 |
| 90 @Override |
| 91 public void setAdapter(final Adapter adapter) { |
| 92 super.setAdapter(adapter); |
| 93 adapter.registerAdapterDataObserver(new AdapterDataObserver() { |
| 94 @Override |
| 95 public void onChanged() { |
| 96 super.onChanged(); |
| 97 updateEmptyViewVisibility(adapter); |
| 98 } |
| 99 |
| 100 @Override |
| 101 public void onItemRangeInserted(int positionStart, int itemCount) { |
| 102 super.onItemRangeInserted(positionStart, itemCount); |
| 103 updateEmptyViewVisibility(adapter); |
| 104 } |
| 105 |
| 106 @Override |
| 107 public void onItemRangeRemoved(int positionStart, int itemCount) { |
| 108 super.onItemRangeRemoved(positionStart, itemCount); |
| 109 updateEmptyViewVisibility(adapter); |
| 110 } |
| 111 }); |
| 112 updateEmptyViewVisibility(adapter); |
| 113 } |
| 114 |
| 115 @Override |
| 116 public EnhancedBookmarkItemsAdapter getAdapter() { |
| 117 return (EnhancedBookmarkItemsAdapter) super.getAdapter(); |
| 118 } |
| 119 |
| 120 @Override |
| 121 public GridLayoutManager getLayoutManager() { |
| 122 return (GridLayoutManager) super.getLayoutManager(); |
| 123 } |
| 124 |
| 125 /** |
| 126 * Unlike ListView or GridView, RecyclerView does not provide default empty |
| 127 * view implementation. We need to check it ourselves. |
| 128 */ |
| 129 private void updateEmptyViewVisibility(Adapter adapter) { |
| 130 mEmptyView.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : Vi
ew.GONE); |
| 131 } |
| 132 |
| 133 private void setMargin(int marginInPx) { |
| 134 RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayout
Params(); |
| 135 lp.setMargins(marginInPx, marginInPx, marginInPx, marginInPx); |
| 136 setLayoutParams(lp); |
| 137 } |
| 138 |
| 139 // EnhancedBookmarkUIObserver implementations |
| 140 |
| 141 @Override |
| 142 public void onEnhancedBookmarkDelegateInitialized(EnhancedBookmarkDelegate d
elegate) { |
| 143 mDelegate = delegate; |
| 144 mDelegate.addUIObserver(this); |
| 145 |
| 146 EnhancedBookmarkItemsAdapter adapter = new EnhancedBookmarkItemsAdapter(
getContext()); |
| 147 adapter.onEnhancedBookmarkDelegateInitialized(mDelegate); |
| 148 setAdapter(adapter); |
| 149 |
| 150 getLayoutManager().setSpanSizeLookup(new SpanSizeLookup() { |
| 151 @Override |
| 152 public int getSpanSize(int position) { |
| 153 return getAdapter().isHeader(position) ? getLayoutManager().getS
panCount() : 1; |
| 154 } |
| 155 }); |
| 156 } |
| 157 |
| 158 @Override |
| 159 public void onDestroy() { |
| 160 mDelegate.removeUIObserver(this); |
| 161 } |
| 162 |
| 163 @Override |
| 164 public void onAllBookmarksStateSet() { |
| 165 scrollToPosition(0); |
| 166 } |
| 167 |
| 168 @Override |
| 169 public void onFolderStateSet(BookmarkId folder) { |
| 170 scrollToPosition(0); |
| 171 } |
| 172 |
| 173 @Override |
| 174 public void onFilterStateSet(String filter) { |
| 175 scrollToPosition(0); |
| 176 } |
| 177 |
| 178 @Override |
| 179 public void onSelectionStateChange(List<BookmarkId> selectedBookmarks) { |
| 180 if (!mDelegate.isSelectionEnabled()) { |
| 181 for (int i = 0; i < getLayoutManager().getChildCount(); ++i) { |
| 182 View child = getLayoutManager().getChildAt(i); |
| 183 if (child instanceof Checkable) ((Checkable) child).setChecked(f
alse); |
| 184 } |
| 185 } |
| 186 } |
| 187 |
| 188 @Override |
| 189 public void onListModeChange(final boolean isListModeEnabled) { |
| 190 if (isListModeEnabled) { |
| 191 removeItemDecoration(mItemDecoration); |
| 192 setPadding(0, 0, 0, 0); |
| 193 getLayoutManager().setSpanCount(1); |
| 194 |
| 195 if (isLargeTablet(getContext())) { |
| 196 setClipToPadding(true); |
| 197 setBackgroundResource(R.drawable.eb_item_tile); |
| 198 setMargin(getContext().getResources().getDimensionPixelSize( |
| 199 R.dimen.enhanced_bookmark_list_mode_background_margin)); |
| 200 } else { |
| 201 setBackgroundColor(getContext().getResources().getColor(android.
R.color.white)); |
| 202 } |
| 203 } else { |
| 204 addItemDecoration(mItemDecoration); |
| 205 setPadding(mItemHalfSpacePx, mItemHalfSpacePx, mItemHalfSpacePx, mIt
emHalfSpacePx); |
| 206 |
| 207 if (isLargeTablet(getContext())) { |
| 208 setClipToPadding(false); |
| 209 setBackgroundResource(0); |
| 210 setMargin(0); |
| 211 } else { |
| 212 setBackgroundColor( |
| 213 getContext().getResources().getColor(R.color.default_pri
mary_color)); |
| 214 } |
| 215 requestLayout(); |
| 216 } |
| 217 |
| 218 // TODO(ianwen): remember scroll position and scroll back after mode swi
tching. |
| 219 mDelegate.notifyStateChange(this); |
| 220 } |
| 221 } |
OLD | NEW |