From 126415980ff90018626aba92a94ced0678a2f668 Mon Sep 17 00:00:00 2001 From: renpeng Date: Tue, 9 Oct 2018 20:07:57 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9section=E8=AE=BE?= =?UTF-8?q?=E5=AE=9A=E9=97=B4=E8=B7=9D=E5=90=8E=EF=BC=8C=E6=9D=A1=E7=9B=AE?= =?UTF-8?q?=E5=AE=BD=E5=BA=A6=E8=87=AA=E9=80=82=E5=BA=94=E7=9A=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SectionUseActivity.java | 2 + .../GridAverageGapSectionItemDecoration.java | 143 ++++++++++++++++++ .../main/res/layout/item_section_content.xml | 2 - 3 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java index ae2987524..5e3df893a 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java @@ -9,6 +9,7 @@ import com.chad.baserecyclerviewadapterhelper.adapter.SectionAdapter; import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; import com.chad.baserecyclerviewadapterhelper.data.DataServer; +import com.chad.baserecyclerviewadapterhelper.decoration.GridAverageGapSectionItemDecoration; import com.chad.baserecyclerviewadapterhelper.entity.MySection; import com.chad.library.adapter.base.BaseQuickAdapter; @@ -29,6 +30,7 @@ protected void onCreate(Bundle savedInstanceState) { setTitle("Section Use"); mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); + mRecyclerView.addItemDecoration(new GridAverageGapSectionItemDecoration(50,20,20,20)); mData = DataServer.getSampleData(); SectionAdapter sectionAdapter = new SectionAdapter(R.layout.item_section_content, R.layout.def_section_head, mData); diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java new file mode 100644 index 000000000..9aa006906 --- /dev/null +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java @@ -0,0 +1,143 @@ +package com.chad.baserecyclerviewadapterhelper.decoration; + +import android.graphics.Rect; +import android.support.v7.widget.GridLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.util.DisplayMetrics; +import android.util.Log; +import android.util.TypedValue; +import android.view.View; + +import com.chad.library.adapter.base.BaseQuickAdapter; +import com.chad.library.adapter.base.BaseSectionQuickAdapter; +import com.chad.library.adapter.base.BaseViewHolder; +import com.chad.library.adapter.base.entity.SectionEntity; + +/** + * 应用于RecyclerView的GridLayoutManager,水平方向上固定间距大小,从而使条目宽度自适应。
+ * 配合Brvah的Section使用,不对Head生效,仅对每个Head的子Grid列表生效
+ *Section Grid中Item的宽度应设为MATCH_PARAENT + * + * @author : renpeng + * @org :Aurora Team + * @since : 2018/9/29 + */ +public class GridAverageGapSectionItemDecoration extends RecyclerView.ItemDecoration { + + private float gapHorizontalDp; + private float gapVerticalDp; + private float sectionEdgeHPaddingDp; + private float sectionEdgeVPaddingDp; + private int gapHSizePx = -1; + private int gapVSizePx = -1; + private int sectionEdgeHPaddingPx; + private int eachItemHPaddingPx; //每个条目应该在水平方向上加的padding 总大小,即=paddingLeft+paddingRight + private int sectionEdgeVPaddingPx; + private Rect preRect = new Rect(); + private boolean isPreItemHeader = false; + private int sectionStartItemPos = 0; + private int sectionEndItemPos = 0; + private int sectionItemCount = 0; + + /** + * @param gapHorizontalDp 水平间距 + * @param gapVerticalDp 垂直间距 + * @param sectionEdgeHPaddingDp 左右两端的padding大小 + * @param sectionEdgeVPaddingDp 上下两端的padding大小 + */ + public GridAverageGapSectionItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) { + this.gapHorizontalDp = gapHorizontalDp; + this.gapVerticalDp = gapVerticalDp; + this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp; + this.sectionEdgeVPaddingDp = sectionEdgeVPaddingDp; + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (parent.getLayoutManager() instanceof GridLayoutManager && parent.getAdapter() instanceof BaseSectionQuickAdapter) { + GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager(); + BaseSectionQuickAdapter adapter = (BaseSectionQuickAdapter) parent.getAdapter(); + int spanCount = layoutManager.getSpanCount(); + int position = parent.getChildAdapterPosition(view); + SectionEntity entity = adapter.getItem(position); + + if (entity != null && entity.isHeader) { + //不处理header + isPreItemHeader = true; + outRect.set(0,0,0,0); +// Log.w("GridAverageGapItem", "pos=" + position + "," + outRect.toShortString()); + return; + } + + if (isPreItemHeader) { + sectionStartItemPos = position; + sectionEndItemPos = findSectionLastItemPos(position, adapter); + sectionItemCount = sectionEndItemPos - sectionStartItemPos + 1; +// Log.w("GridAverageGapItem", "new section=" + sectionStartItemPos + "-" + sectionEndItemPos); + } + + if (gapHSizePx < 0 || gapVSizePx < 0) { + DisplayMetrics displayMetrics = new DisplayMetrics(); + parent.getDisplay().getMetrics(displayMetrics); + gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics); + gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics); + sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics); + sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics); + eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount; + } + outRect.top = gapVSizePx; + outRect.bottom = 0; + + //下面的visualPos为单个Section内的视觉Pos + int visualPos = position + 1 - sectionStartItemPos; + if (visualPos % spanCount == 1) { + //第一列 + outRect.left = sectionEdgeHPaddingPx; + outRect.right = eachItemHPaddingPx - sectionEdgeHPaddingPx; + } else if (visualPos % spanCount == 0) { + //最后一列 + outRect.left = eachItemHPaddingPx - sectionEdgeHPaddingPx; + outRect.right = sectionEdgeHPaddingPx; + } else { + outRect.left = gapHSizePx - preRect.right; + outRect.right = eachItemHPaddingPx - outRect.left; + } + + if (visualPos - spanCount <= 0) { + //每个section的第一行 + outRect.top = sectionEdgeVPaddingPx; + } + //存在即是第一行,又是最后一行的情况,故不用elseif + if (isLastRow(visualPos, spanCount, sectionItemCount)) { + //每个section的最后一行 + outRect.bottom = sectionEdgeVPaddingPx; + } + preRect = new Rect(outRect); + isPreItemHeader = false; +// Log.w("GridAverageGapItem", "pos=" + position + "," + outRect.toShortString()); + } else { + super.getItemOffsets(outRect, view, parent, state); + } + } + + private int findSectionLastItemPos(int curPos, BaseQuickAdapter adapter) { + int count = adapter.getItemCount(); + if (count == curPos + 1) { + return curPos; + } + SectionEntity sectionEntity = null; + for (int i = curPos + 1; i < count; i++) { + sectionEntity = adapter.getItem(i); + if (sectionEntity != null && sectionEntity.isHeader) { + return i - 1; + } + } + return count - 1; + } + + private boolean isLastRow(int visualPos, int spanCount, int sectionItemCount) { + int lastRowCount = sectionItemCount % spanCount; + lastRowCount = lastRowCount == 0 ? spanCount : lastRowCount; + return visualPos > sectionItemCount - lastRowCount; + } +} diff --git a/app/src/main/res/layout/item_section_content.xml b/app/src/main/res/layout/item_section_content.xml index c6d9ba0c1..4d072f82d 100644 --- a/app/src/main/res/layout/item_section_content.xml +++ b/app/src/main/res/layout/item_section_content.xml @@ -6,8 +6,6 @@ android:layout_width="match_parent" android:layout_height="150dp" android:layout_gravity="center" - android:layout_marginLeft="5dp" - android:layout_marginRight="5dp" android:foreground="?android:attr/selectableItemBackground" card_view:cardBackgroundColor="@android:color/white" card_view:cardCornerRadius="4dp" From 085faa35ce7af1832ee8c1c3757d1ece5548f373 Mon Sep 17 00:00:00 2001 From: renpeng Date: Mon, 15 Oct 2018 15:31:08 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=83=A8=E5=88=86?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SectionUseActivity.java | 4 ++-- ... GridSectionAverageGapItemDecoration.java} | 23 +++++++++++-------- 2 files changed, 15 insertions(+), 12 deletions(-) rename app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/{GridAverageGapSectionItemDecoration.java => GridSectionAverageGapItemDecoration.java} (85%) diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java index 5e3df893a..15b9f6372 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/SectionUseActivity.java @@ -9,7 +9,7 @@ import com.chad.baserecyclerviewadapterhelper.adapter.SectionAdapter; import com.chad.baserecyclerviewadapterhelper.base.BaseActivity; import com.chad.baserecyclerviewadapterhelper.data.DataServer; -import com.chad.baserecyclerviewadapterhelper.decoration.GridAverageGapSectionItemDecoration; +import com.chad.baserecyclerviewadapterhelper.decoration.GridSectionAverageGapItemDecoration; import com.chad.baserecyclerviewadapterhelper.entity.MySection; import com.chad.library.adapter.base.BaseQuickAdapter; @@ -30,7 +30,7 @@ protected void onCreate(Bundle savedInstanceState) { setTitle("Section Use"); mRecyclerView = (RecyclerView) findViewById(R.id.rv_list); mRecyclerView.setLayoutManager(new GridLayoutManager(this,2)); - mRecyclerView.addItemDecoration(new GridAverageGapSectionItemDecoration(50,20,20,20)); + mRecyclerView.addItemDecoration(new GridSectionAverageGapItemDecoration(50,20,20,20)); mData = DataServer.getSampleData(); SectionAdapter sectionAdapter = new SectionAdapter(R.layout.item_section_content, R.layout.def_section_head, mData); diff --git a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java similarity index 85% rename from app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java rename to app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java index 9aa006906..92de88809 100644 --- a/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridAverageGapSectionItemDecoration.java +++ b/app/src/main/java/com/chad/baserecyclerviewadapterhelper/decoration/GridSectionAverageGapItemDecoration.java @@ -4,7 +4,6 @@ import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.DisplayMetrics; -import android.util.Log; import android.util.TypedValue; import android.view.View; @@ -22,7 +21,7 @@ * @org :Aurora Team * @since : 2018/9/29 */ -public class GridAverageGapSectionItemDecoration extends RecyclerView.ItemDecoration { +public class GridSectionAverageGapItemDecoration extends RecyclerView.ItemDecoration { private float gapHorizontalDp; private float gapVerticalDp; @@ -45,7 +44,7 @@ public class GridAverageGapSectionItemDecoration extends RecyclerView.ItemDecora * @param sectionEdgeHPaddingDp 左右两端的padding大小 * @param sectionEdgeVPaddingDp 上下两端的padding大小 */ - public GridAverageGapSectionItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) { + public GridSectionAverageGapItemDecoration(float gapHorizontalDp, float gapVerticalDp, float sectionEdgeHPaddingDp, float sectionEdgeVPaddingDp) { this.gapHorizontalDp = gapHorizontalDp; this.gapVerticalDp = gapVerticalDp; this.sectionEdgeHPaddingDp = sectionEdgeHPaddingDp; @@ -77,13 +76,7 @@ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, Recycle } if (gapHSizePx < 0 || gapVSizePx < 0) { - DisplayMetrics displayMetrics = new DisplayMetrics(); - parent.getDisplay().getMetrics(displayMetrics); - gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics); - gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics); - sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics); - sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics); - eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount; + transformGapDefinition(parent, spanCount); } outRect.top = gapVSizePx; outRect.bottom = 0; @@ -120,6 +113,16 @@ public void getItemOffsets(Rect outRect, View view, RecyclerView parent, Recycle } } + private void transformGapDefinition(RecyclerView parent, int spanCount) { + DisplayMetrics displayMetrics = new DisplayMetrics(); + parent.getDisplay().getMetrics(displayMetrics); + gapHSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapHorizontalDp, displayMetrics); + gapVSizePx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, gapVerticalDp, displayMetrics); + sectionEdgeHPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeHPaddingDp, displayMetrics); + sectionEdgeVPaddingPx = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, sectionEdgeVPaddingDp, displayMetrics); + eachItemHPaddingPx = (sectionEdgeHPaddingPx * 2 + gapHSizePx * (spanCount - 1)) / spanCount; + } + private int findSectionLastItemPos(int curPos, BaseQuickAdapter adapter) { int count = adapter.getItemCount(); if (count == curPos + 1) {