Skip to content

Commit

Permalink
Merge pull request #2492 from candyguy242/master
Browse files Browse the repository at this point in the history
增加对section设定间距后,条目宽度自适应的功能
  • Loading branch information
AllenCoder authored Dec 3, 2018
2 parents 0de833d + 085faa3 commit 4adb205
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.GridSectionAverageGapItemDecoration;
import com.chad.baserecyclerviewadapterhelper.entity.MySection;
import com.chad.library.adapter.base.BaseQuickAdapter;

Expand All @@ -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 GridSectionAverageGapItemDecoration(50,20,20,20));
mData = DataServer.getSampleData();
SectionAdapter sectionAdapter = new SectionAdapter(R.layout.item_section_content, R.layout.def_section_head, mData);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
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.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,水平方向上固定间距大小,从而使条目宽度自适应。<br>
* 配合Brvah的Section使用,不对Head生效,仅对每个Head的子Grid列表生效<br>
*Section Grid中Item的宽度应设为MATCH_PARAENT
*
* @author : renpeng
* @org :Aurora Team
* @since : 2018/9/29
*/
public class GridSectionAverageGapItemDecoration 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 GridSectionAverageGapItemDecoration(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<SectionEntity, BaseViewHolder> 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) {
transformGapDefinition(parent, 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 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<SectionEntity, BaseViewHolder> 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;
}
}
2 changes: 0 additions & 2 deletions app/src/main/res/layout/item_section_content.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 4adb205

Please sign in to comment.