diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java index 23702d899..3c017bcd4 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java @@ -26,7 +26,6 @@ import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Spannable; @@ -75,6 +74,7 @@ import com.hippo.util.DrawableManager; import com.hippo.widget.ContentLayout; import com.hippo.widget.FabLayout; import com.hippo.widget.SearchBarMover; +import com.hippo.widget.recyclerview.GridAutoSpanLayoutManager; import com.hippo.widget.refreshlayout.RefreshLayout; import com.hippo.yorozuya.ObjectUtils; import com.hippo.yorozuya.SimpleHandler; @@ -255,7 +255,7 @@ public class FavoritesScene extends BaseScene implements contentLayout.setHelper(mHelper); contentLayout.getFastScroller().setOnDragHandlerListener(this); - GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 1); + GridAutoSpanLayoutManager layoutManager = new GridAutoSpanLayoutManager(getContext(), 0); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setSelector(RippleSalon.generateRippleDrawable(false)); mRecyclerView.setDrawSelectorOnTop(true); @@ -931,7 +931,7 @@ public class FavoritesScene extends BaseScene implements private class FavoritesAdapter extends GalleryAdapter { public FavoritesAdapter(LayoutInflater inflater, Context context, - RecyclerView recyclerView, GridLayoutManager layoutManager, int type) { + RecyclerView recyclerView, GridAutoSpanLayoutManager layoutManager, int type) { super(inflater, context, recyclerView, layoutManager, type); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java index e1dfe4fe0..e64fea1f6 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryAdapter.java @@ -23,7 +23,6 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.support.annotation.IntDef; import android.support.annotation.Nullable; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -39,7 +38,7 @@ import com.hippo.ehviewer.client.EhCacheKeyFactory; import com.hippo.ehviewer.client.EhUtils; import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.util.ApiHelper; -import com.hippo.util.LayoutUtils2; +import com.hippo.widget.recyclerview.GridAutoSpanLayoutManager; import com.hippo.yorozuya.Messenger; import java.lang.annotation.Retention; @@ -59,12 +58,12 @@ abstract class GalleryAdapter extends RecyclerView.Adapter implem private final Context mContext; private final Resources mResources; private final RecyclerView mRecyclerView; - private final GridLayoutManager mLayoutManager; + private final GridAutoSpanLayoutManager mLayoutManager; private RecyclerView.ItemDecoration mGirdDecoration; private int mType = TYPE_INVALID; public GalleryAdapter(LayoutInflater inflater, Context context, - RecyclerView recyclerView, GridLayoutManager layoutManager, int type) { + RecyclerView recyclerView, GridAutoSpanLayoutManager layoutManager, int type) { mInflater = inflater; mContext = context; mResources = context.getResources(); @@ -90,9 +89,9 @@ abstract class GalleryAdapter extends RecyclerView.Adapter implem switch (type) { default: case GalleryAdapter.TYPE_LIST: { - int minWidth = mResources.getDimensionPixelOffset(R.dimen.gallery_list_min_width); - int spanCount = LayoutUtils2.calculateSpanCount(mContext, minWidth); - mLayoutManager.setSpanCount(spanCount); + int columnWidth = mResources.getDimensionPixelOffset(R.dimen.gallery_list_column_width); + mLayoutManager.setColumnSize(columnWidth); + mLayoutManager.setStrategy(GridAutoSpanLayoutManager.STRATEGY_MIN_SIZE); if (null != mGirdDecoration) { mRecyclerView.removeItemDecoration(mGirdDecoration); } @@ -100,9 +99,9 @@ abstract class GalleryAdapter extends RecyclerView.Adapter implem break; } case GalleryAdapter.TYPE_GRID: { - int minWidth = mResources.getDimensionPixelOffset(R.dimen.gallery_grid_min_width); - int spanCount = LayoutUtils2.calculateSpanCount(mContext, minWidth); - mLayoutManager.setSpanCount(spanCount); + int columnWidth = mResources.getDimensionPixelOffset(R.dimen.gallery_grid_column_width); + mLayoutManager.setColumnSize(columnWidth); + mLayoutManager.setStrategy(GridAutoSpanLayoutManager.STRATEGY_SUITABLE_SIZE); if (null == mGirdDecoration) { mGirdDecoration = new MarginItemDecoration( mResources.getDimensionPixelOffset(R.dimen.list_content_interval)); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index 44bb16baf..79d326521 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -87,14 +87,13 @@ import com.hippo.util.ActivityHelper; import com.hippo.util.ApiHelper; import com.hippo.util.DrawableManager; import com.hippo.util.ExceptionUtils; -import com.hippo.util.LayoutUtils2; import com.hippo.util.ReadableTime; import com.hippo.view.ViewTransition; import com.hippo.widget.AutoWrapLayout; import com.hippo.widget.LoadImageView; import com.hippo.widget.ProgressView; import com.hippo.widget.ProgressiveRatingBar; -import com.hippo.widget.SimpleGridLayout; +import com.hippo.widget.recyclerview.SimpleGridAutoSpanLayout; import com.hippo.yorozuya.SimpleHandler; import com.hippo.yorozuya.ViewUtils; @@ -208,7 +207,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene @Nullable private View mPreviews; @Nullable - private SimpleGridLayout mGridLayout; + private SimpleGridAutoSpanLayout mGridLayout; @Nullable private TextView mPreviewText; // Progress @@ -462,7 +461,7 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene mComments.setOnClickListener(this); mPreviews = ViewUtils.$$(belowHeader, R.id.previews); - mGridLayout = (SimpleGridLayout) ViewUtils.$$(mPreviews, R.id.grid_layout); + mGridLayout = (SimpleGridAutoSpanLayout) ViewUtils.$$(mPreviews, R.id.grid_layout); mPreviewText = (TextView) ViewUtils.$$(mPreviews, R.id.preview_text); RippleSalon.addRipple(mPreviews, false); mPreviews.setOnClickListener(this); @@ -849,10 +848,9 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene mPreviewText.setText(R.string.more_previews); } - int minWidth = getResources().getDimensionPixelOffset(R.dimen.preview_grid_min_width); - int spanCount = LayoutUtils2.calculateSpanCount(getContext(), minWidth); - mGridLayout.setColumnCount(spanCount); - + int columnWidth = getResources().getDimensionPixelOffset(R.dimen.preview_grid_column_width); + mGridLayout.setColumnSize(columnWidth); + mGridLayout.setStrategy(SimpleGridAutoSpanLayout.STRATEGY_SUITABLE_SIZE); LayoutInflater inflater = getActivity().getLayoutInflater(); for (int i = 0, size = previewSet.size(); i < size; i++) { View view = inflater.inflate(R.layout.item_gallery_preview, mGridLayout, false); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index c1ac6c0ec..1903d324e 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -29,7 +29,6 @@ import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.text.Spannable; @@ -79,6 +78,7 @@ import com.hippo.util.DrawableManager; import com.hippo.view.ViewTransition; import com.hippo.widget.ContentLayout; import com.hippo.widget.SearchBarMover; +import com.hippo.widget.recyclerview.GridAutoSpanLayoutManager; import com.hippo.widget.refreshlayout.RefreshLayout; import com.hippo.yorozuya.AnimationUtils; import com.hippo.yorozuya.MathUtils; @@ -355,7 +355,7 @@ public final class GalleryListScene extends BaseScene contentLayout.setHelper(mHelper); contentLayout.getFastScroller().setOnDragHandlerListener(this); - GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 1); + GridAutoSpanLayoutManager layoutManager = new GridAutoSpanLayoutManager(getContext(), 0); mRecyclerView.setLayoutManager(layoutManager); mRecyclerView.setSelector(RippleSalon.generateRippleDrawable(false)); mRecyclerView.setDrawSelectorOnTop(true); @@ -946,7 +946,7 @@ public final class GalleryListScene extends BaseScene private class GalleryListAdapter extends GalleryAdapter { public GalleryListAdapter(LayoutInflater inflater, Context context, - RecyclerView recyclerView, GridLayoutManager layoutManager, int type) { + RecyclerView recyclerView, GridAutoSpanLayoutManager layoutManager, int type) { super(inflater, context, recyclerView, layoutManager, type); } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java index 508c7e9cd..44b88d58a 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java @@ -25,7 +25,6 @@ import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Pair; import android.view.LayoutInflater; @@ -49,10 +48,10 @@ import com.hippo.ehviewer.client.exception.EhException; import com.hippo.ehviewer.ui.GalleryActivity; import com.hippo.scene.SceneFragment; import com.hippo.scene.StageActivity; -import com.hippo.util.LayoutUtils2; import com.hippo.widget.ContentLayout; import com.hippo.widget.LoadImageView; import com.hippo.widget.Slider; +import com.hippo.widget.recyclerview.GridAutoSpanLayoutManager; import com.hippo.yorozuya.LayoutUtils; import com.hippo.yorozuya.SimpleHandler; @@ -133,9 +132,10 @@ public class GalleryPreviewsScene extends ToolbarScene implements EasyRecyclerVi mAdapter = new GalleryPreviewAdapter(); recyclerView.setAdapter(mAdapter); - int minWidth = getResources().getDimensionPixelOffset(R.dimen.preview_grid_min_width); - int spanCount = LayoutUtils2.calculateSpanCount(getContext(), minWidth); - recyclerView.setLayoutManager(new GridLayoutManager(getContext(), spanCount)); + int columnWidth = getResources().getDimensionPixelOffset(R.dimen.preview_grid_column_width); + GridAutoSpanLayoutManager layoutManager = new GridAutoSpanLayoutManager(getContext(), columnWidth); + layoutManager.setStrategy(GridAutoSpanLayoutManager.STRATEGY_SUITABLE_SIZE); + recyclerView.setLayoutManager(layoutManager); int padding = LayoutUtils.dp2pix(getContext(), 4); recyclerView.setPadding(padding, padding, padding, padding); recyclerView.setClipToPadding(false); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.java index 27e2deff2..d5a373818 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/HistoryScene.java @@ -22,7 +22,6 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -47,6 +46,7 @@ import com.hippo.scene.StageActivity; import com.hippo.util.ApiHelper; import com.hippo.util.DrawableManager; import com.hippo.view.ViewTransition; +import com.hippo.widget.recyclerview.GridAutoSpanLayoutManager; import com.hippo.yorozuya.ResourcesUtils; import com.hippo.yorozuya.ViewUtils; @@ -87,7 +87,7 @@ public class HistoryScene extends ToolbarScene tip.setCompoundDrawables(null, drawable, null, null); mList = EhDB.getHistoryLazyList(); - GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 1); + GridAutoSpanLayoutManager layoutManager = new GridAutoSpanLayoutManager(getContext(), 0); recyclerView.setLayoutManager(layoutManager); recyclerView.setSelector(RippleSalon.generateRippleDrawable(false)); recyclerView.setDrawSelectorOnTop(true); @@ -191,7 +191,7 @@ public class HistoryScene extends ToolbarScene private class HistoryAdapter extends GalleryAdapter { public HistoryAdapter(LayoutInflater inflater, Context context, - RecyclerView recyclerView, GridLayoutManager layoutManager, int type) { + RecyclerView recyclerView, GridAutoSpanLayoutManager layoutManager, int type) { super(inflater, context, recyclerView, layoutManager, type); } diff --git a/app/src/main/java/com/hippo/util/LayoutUtils2.java b/app/src/main/java/com/hippo/util/LayoutUtils2.java deleted file mode 100644 index 712e48cc5..000000000 --- a/app/src/main/java/com/hippo/util/LayoutUtils2.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2016 Hippo Seven - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.util; - -import android.content.Context; -import android.graphics.Point; -import android.view.Display; -import android.view.WindowManager; - -import com.hippo.yorozuya.MathUtils; - -public final class LayoutUtils2 { - - private static final Point sPoint = new Point(); - - private LayoutUtils2() {} - - public static int calculateSpanCount(Context context, int minWidth) { - WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - Display display = wm.getDefaultDisplay(); - display.getSize(sPoint); - int width = sPoint.x; - return MathUtils.clamp(width / minWidth, 1, Integer.MAX_VALUE); - } -} diff --git a/app/src/main/java/com/hippo/widget/recyclerview/GridAutoSpanLayoutManager.java b/app/src/main/java/com/hippo/widget/recyclerview/GridAutoSpanLayoutManager.java new file mode 100644 index 000000000..0d304bbbc --- /dev/null +++ b/app/src/main/java/com/hippo/widget/recyclerview/GridAutoSpanLayoutManager.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.widget.recyclerview; + +import android.content.Context; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; + +public class GridAutoSpanLayoutManager extends GridLayoutManager { + + public static final int STRATEGY_MIN_SIZE = 0; + public static final int STRATEGY_SUITABLE_SIZE = 1; + + private int mColumnSize = -1; + private boolean mColumnSizeChanged = true; + private int mStrategy; + + public GridAutoSpanLayoutManager(Context context, int columnSize) { + super(context, 1); + setColumnSize(columnSize); + } + + public GridAutoSpanLayoutManager(Context context, int columnSize, int orientation, boolean reverseLayout) { + super(context, 1, orientation, reverseLayout); + setColumnSize(columnSize); + } + + public void setColumnSize(int columnSize) { + if (columnSize == mColumnSize) { + return; + } + mColumnSize = columnSize; + mColumnSizeChanged = true; + } + + public void setStrategy(int strategy) { + if (strategy == mStrategy) { + return; + } + mStrategy = strategy; + mColumnSizeChanged = true; + } + + public static int getSpanCountForSuitableSize(int total, int single) { + int span = total / single; + if (span <= 0) { + return 1; + } + int span2 = span + 1; + float deviation = Math.abs(1 - (total / span / (float) single)); + float deviation2 = Math.abs(1 - (total / span2 / (float) single)); + return deviation < deviation2 ? span : span2; + } + + public static int getSpanCountForMinSize(int total, int single) { + return Math.max(1, total / single); + } + + @Override + public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { + if (mColumnSizeChanged && mColumnSize > 0) { + int totalSpace; + if (getOrientation() == VERTICAL) { + totalSpace = getWidth() - getPaddingRight() - getPaddingLeft(); + } else { + totalSpace = getHeight() - getPaddingTop() - getPaddingBottom(); + } + + int spanCount; + switch (mStrategy) { + default: + case STRATEGY_MIN_SIZE: + spanCount = getSpanCountForMinSize(totalSpace, mColumnSize); + break; + case STRATEGY_SUITABLE_SIZE: + spanCount = getSpanCountForSuitableSize(totalSpace, mColumnSize); + break; + } + setSpanCount(spanCount); + mColumnSizeChanged = false; + } + super.onLayoutChildren(recycler, state); + } +} diff --git a/app/src/main/java/com/hippo/widget/recyclerview/SimpleGridAutoSpanLayout.java b/app/src/main/java/com/hippo/widget/recyclerview/SimpleGridAutoSpanLayout.java new file mode 100644 index 000000000..172b926a9 --- /dev/null +++ b/app/src/main/java/com/hippo/widget/recyclerview/SimpleGridAutoSpanLayout.java @@ -0,0 +1,98 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.widget.recyclerview; + +import android.content.Context; +import android.util.AttributeSet; + +import com.hippo.widget.SimpleGridLayout; + +public class SimpleGridAutoSpanLayout extends SimpleGridLayout { + + public static final int STRATEGY_MIN_SIZE = 0; + public static final int STRATEGY_SUITABLE_SIZE = 1; + + private int mColumnSize = -1; + private boolean mColumnSizeChanged = true; + private int mStrategy; + + public SimpleGridAutoSpanLayout(Context context) { + super(context); + } + + public SimpleGridAutoSpanLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public SimpleGridAutoSpanLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void setColumnSize(int columnSize) { + if (columnSize == mColumnSize) { + return; + } + mColumnSize = columnSize; + mColumnSizeChanged = true; + } + + public void setStrategy(int strategy) { + if (strategy == mStrategy) { + return; + } + mStrategy = strategy; + mColumnSizeChanged = true; + } + + public static int getSpanCountForSuitableSize(int total, int single) { + int span = total / single; + if (span <= 0) { + return 1; + } + int span2 = span + 1; + float deviation = Math.abs(1 - (total / span / (float) single)); + float deviation2 = Math.abs(1 - (total / span2 / (float) single)); + return deviation < deviation2 ? span : span2; + } + + public static int getSpanCountForMinSize(int total, int single) { + return Math.max(1, total / single); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthMode = MeasureSpec.getMode(widthMeasureSpec); + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + + if (mColumnSizeChanged && mColumnSize > 0 && widthMode == MeasureSpec.EXACTLY) { + int totalSpace = widthSize - getPaddingRight() - getPaddingLeft(); + int spanCount; + switch (mStrategy) { + default: + case STRATEGY_MIN_SIZE: + spanCount = getSpanCountForMinSize(totalSpace, mColumnSize); + break; + case STRATEGY_SUITABLE_SIZE: + spanCount = getSpanCountForSuitableSize(totalSpace, mColumnSize); + break; + } + setColumnCount(spanCount); + mColumnSizeChanged = false; + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } +} diff --git a/app/src/main/res/layout/gallery_detail_previews.xml b/app/src/main/res/layout/gallery_detail_previews.xml index 416064411..9dded5458 100644 --- a/app/src/main/res/layout/gallery_detail_previews.xml +++ b/app/src/main/res/layout/gallery_detail_previews.xml @@ -25,7 +25,7 @@ android:divider="@drawable/spacer_keyline" android:showDividers="middle"> - 77dp 80dp - 240dp - 80dp - 80dp + 320dp + 100dp + 100dp 24dp