Bug 1310081 - 1. Move SpacingDecoration and introduce AutoFitRecyclerView. r?sebastian
Make PanelRecylerView an AutoFitRecyclerView.
These changes are in preparation for making TabsGridLayout a RecyclerView.
MozReview-Commit-ID: 1W0I6yaPVO5
--- a/mobile/android/base/java/org/mozilla/gecko/home/PanelRecyclerView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/home/PanelRecyclerView.java
@@ -3,69 +3,73 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.home;
import org.mozilla.gecko.R;
import org.mozilla.gecko.home.PanelLayout.DatasetBacked;
import org.mozilla.gecko.home.PanelLayout.PanelView;
+import org.mozilla.gecko.widget.AutoFitRecyclerView;
import org.mozilla.gecko.widget.RecyclerViewClickSupport;
import org.mozilla.gecko.widget.RecyclerViewClickSupport.OnItemClickListener;
import org.mozilla.gecko.widget.RecyclerViewClickSupport.OnItemLongClickListener;
+import org.mozilla.gecko.widget.SpacingDecoration;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* RecyclerView implementation for grid home panels.
*/
@SuppressLint("ViewConstructor") // View is only created from code
-public class PanelRecyclerView extends RecyclerView
+public class PanelRecyclerView extends AutoFitRecyclerView
implements DatasetBacked, PanelView, OnItemClickListener, OnItemLongClickListener {
private final PanelRecyclerViewAdapter adapter;
private final GridLayoutManager layoutManager;
private final PanelViewItemHandler itemHandler;
- private final float columnWidth;
- private final boolean autoFit;
private final HomeConfig.ViewConfig viewConfig;
private PanelLayout.OnItemOpenListener itemOpenListener;
private HomeContextMenuInfo contextMenuInfo;
private HomeContextMenuInfo.Factory contextMenuInfoFactory;
public PanelRecyclerView(Context context, HomeConfig.ViewConfig viewConfig) {
super(context);
this.viewConfig = viewConfig;
final Resources resources = context.getResources();
- int spanCount;
+ final boolean autoFit;
+ final int spanCount;
if (viewConfig.getItemType() == HomeConfig.ItemType.ICON) {
autoFit = false;
spanCount = getResources().getInteger(R.integer.panel_icon_grid_view_columns);
} else {
autoFit = true;
spanCount = 1;
}
- columnWidth = resources.getDimension(R.dimen.panel_grid_view_column_width);
layoutManager = new GridLayoutManager(context, spanCount);
adapter = new PanelRecyclerViewAdapter(context, viewConfig);
itemHandler = new PanelViewItemHandler();
layoutManager.setSpanSizeLookup(new PanelSpanSizeLookup());
setLayoutManager(layoutManager);
+ if (autoFit) {
+ setAutoFit(true);
+ setDesiredColumnWidth(resources.getDimension(R.dimen.panel_grid_view_column_width));
+ }
setAdapter(adapter);
int horizontalSpacing = (int) resources.getDimension(R.dimen.panel_grid_view_horizontal_spacing);
int verticalSpacing = (int) resources.getDimension(R.dimen.panel_grid_view_vertical_spacing);
int outerSpacing = (int) resources.getDimension(R.dimen.panel_grid_view_outer_spacing);
addItemDecoration(new SpacingDecoration(horizontalSpacing, verticalSpacing));
@@ -73,27 +77,16 @@ public class PanelRecyclerView extends R
setClipToPadding(false);
RecyclerViewClickSupport.addTo(this)
.setOnItemClickListener(this)
.setOnItemLongClickListener(this);
}
@Override
- protected void onMeasure(int widthSpec, int heightSpec) {
- super.onMeasure(widthSpec, heightSpec);
-
- if (autoFit) {
- // Adjust span based on space available (What GridView does when you say numColumns="auto_fit")
- final int spanCount = (int) Math.max(1, getMeasuredWidth() / columnWidth);
- layoutManager.setSpanCount(spanCount);
- }
- }
-
- @Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
itemHandler.setOnItemOpenListener(itemOpenListener);
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
new file mode 100644
--- /dev/null
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/AutoFitRecyclerView.java
@@ -0,0 +1,90 @@
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.widget;
+
+import android.content.Context;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+
+/**
+ * Currently assumes vertical layout in the autofit case.
+ */
+public abstract class AutoFitRecyclerView extends RecyclerView {
+ private float desiredColumnWidth;
+ // If true then the current layout manager is a GridLayoutManager.
+ private boolean autoFit;
+
+ public AutoFitRecyclerView(Context context) {
+ super(context);
+ autoFit = false;
+ }
+
+ public AutoFitRecyclerView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ autoFit = false;
+ }
+
+ public AutoFitRecyclerView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ autoFit = false;
+ }
+
+ /** AutoFit is turned off whenever a non-GridLayoutManager is set. */
+ @Override
+ public void setLayoutManager(LayoutManager layoutManager) {
+ super.setLayoutManager(layoutManager);
+
+ if (!hasGridLayoutManager()) {
+ autoFit = false;
+ }
+ }
+
+ /**
+ * GridLayoutManager operates on number of columns, not column width - AutoFit sets the number
+ * of columns to be the largest number of {@code desiredColumnWidth}-width columns that will fit
+ * in the available width, so the actual column width can turn out to be larger than
+ * {@code desiredColumnWidth}, or even smaller if {@code desiredColumnWidth} is larger than the
+ * total available width.
+ */
+ protected void setDesiredColumnWidth(float desiredColumnWidth) {
+ this.desiredColumnWidth = desiredColumnWidth;
+ }
+
+ /** AutoFit can be set true only if the current layout manager is a GridLayoutManager. */
+ public void setAutoFit(boolean b) {
+ if (b && hasGridLayoutManager()) {
+ autoFit = true;
+ } else {
+ autoFit = false;
+ }
+ }
+
+ @Override
+ public void onSizeChanged (int w, int h, int oldw, int oldh) {
+ super.onSizeChanged(w, h, oldw, oldh);
+
+ if (!autoFit || w == oldw || desiredColumnWidth <= 0) {
+ return;
+ }
+
+ final int nonPaddingWidth = w - getPaddingLeft() - getPaddingRight();
+ // Adjust span based on space available (what GridView does when you say numColumns="auto_fit").
+ final int spanCount = (int) Math.max(1, nonPaddingWidth / desiredColumnWidth);
+ final GridLayoutManager layoutManager = (GridLayoutManager) getLayoutManager();
+ if (spanCount == layoutManager.getSpanCount()) {
+ return;
+ }
+ layoutManager.setSpanCount(spanCount);
+ onSpanCountChanged();
+ }
+
+ protected void onSpanCountChanged() {}
+
+ private boolean hasGridLayoutManager() {
+ return getLayoutManager() instanceof GridLayoutManager;
+ }
+}
rename from mobile/android/base/java/org/mozilla/gecko/home/SpacingDecoration.java
rename to mobile/android/base/java/org/mozilla/gecko/widget/SpacingDecoration.java
--- a/mobile/android/base/java/org/mozilla/gecko/home/SpacingDecoration.java
+++ b/mobile/android/base/java/org/mozilla/gecko/widget/SpacingDecoration.java
@@ -1,9 +1,14 @@
-package org.mozilla.gecko.home;
+/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+package org.mozilla.gecko.widget;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class SpacingDecoration extends RecyclerView.ItemDecoration {
private final int horizontalSpacing;
private final int verticalSpacing;
--- a/mobile/android/base/moz.build
+++ b/mobile/android/base/moz.build
@@ -494,17 +494,16 @@ gbjar.sources += ['java/org/mozilla/geck
'home/RecentTabsAdapter.java',
'home/RemoteTabsExpandableListState.java',
'home/SearchEngine.java',
'home/SearchEngineAdapter.java',
'home/SearchEngineBar.java',
'home/SearchEngineRow.java',
'home/SearchLoader.java',
'home/SimpleCursorLoader.java',
- 'home/SpacingDecoration.java',
'home/TabMenuStrip.java',
'home/TabMenuStripLayout.java',
'home/TopSitesGridItemView.java',
'home/TopSitesGridView.java',
'home/TopSitesPanel.java',
'home/TopSitesThumbnailView.java',
'home/TwoLinePageRow.java',
'icons/decoders/FaviconDecoder.java',
@@ -742,16 +741,17 @@ gbjar.sources += ['java/org/mozilla/geck
'util/DrawableUtil.java',
'util/ResourceDrawableUtils.java',
'util/TouchTargetUtil.java',
'util/ViewUtil.java',
'widget/ActivityChooserModel.java',
'widget/AllCapsTextView.java',
'widget/AnchoredPopup.java',
'widget/AnimatedHeightLayout.java',
+ 'widget/AutoFitRecyclerView.java',
'widget/BasicColorPicker.java',
'widget/CheckableLinearLayout.java',
'widget/ClickableWhenDisabledEditText.java',
'widget/ContentSecurityDoorHanger.java',
'widget/CropImageView.java',
'widget/DateTimePicker.java',
'widget/DefaultDoorHanger.java',
'widget/DefaultItemAnimatorBase.java',
@@ -769,16 +769,17 @@ gbjar.sources += ['java/org/mozilla/geck
'widget/GeckoPopupMenu.java',
'widget/HistoryDividerItemDecoration.java',
'widget/IconTabWidget.java',
'widget/LoginDoorHanger.java',
'widget/RecyclerViewClickSupport.java',
'widget/ResizablePathDrawable.java',
'widget/RoundedCornerLayout.java',
'widget/SiteLogins.java',
+ 'widget/SpacingDecoration.java',
'widget/SquaredImageView.java',
'widget/SquaredRelativeLayout.java',
'widget/SwipeDismissListViewTouchListener.java',
'widget/TabThumbnailWrapper.java',
'widget/ThumbnailView.java',
'widget/TouchDelegateWithReset.java',
'widget/TwoWayView.java',
'ZoomedView.java',