Skip to content

Commit

Permalink
update 完善分割线设置 & 添加头尾空布局可直接设置layoutId
Browse files Browse the repository at this point in the history
  • Loading branch information
youlookwhat committed Nov 4, 2019
1 parent 85e8496 commit 949c457
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,12 @@ private void init() {
}

/**
* 添加HeaderView;不可重复添加相同的View
* 添加HeaderView
*/
public void addHeaderView(int layoutResId) {
addHeaderView(getLayoutView(layoutResId));
}

public void addHeaderView(View headerView) {
mHeaderTypes.add(HEADER_INIT_INDEX + mHeaderViews.size());
mHeaderViews.add(headerView);
Expand Down Expand Up @@ -342,7 +346,7 @@ public boolean onTouchEvent(MotionEvent ev) {
// ==0 原点向下惯性滑动会有效
// 按下的纵坐标 - 当前的纵坐标(为了更灵敏)
mIsScrollUp = mLoadMoreEnabled && mPullStartY - ev.getY() >= -10;
// LogHelper.e("mIsScrollUp: ", mIsScrollUp + " --- mPullStartY: " + mPullStartY + " --- " + "ev.getY(): " + ev.getY());
// Log.e("mIsScrollUp: ", mIsScrollUp + " --- mPullStartY: " + mPullStartY + " --- " + "ev.getY(): " + ev.getY());

mPullStartY = 0;
mLastY = -1;
Expand Down Expand Up @@ -792,11 +796,9 @@ private int getLoadMoreSize() {

/**
* @param layoutResId layoutResId
* @param viewGroup recyclerView.getParent()
*/
public void setEmptyView(int layoutResId, ViewGroup viewGroup) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(layoutResId, viewGroup, false);
setEmptyView(view);
public void setEmptyView(int layoutResId) {
setEmptyView(getLayoutView(layoutResId));
}

/**
Expand Down Expand Up @@ -832,6 +834,19 @@ public void setEmptyView(View emptyView) {
}
}

/**
* 通过 layoutResId 获取Vew
*
* @param layoutResId layoutResId
*/
private View getLayoutView(int layoutResId) {
return LayoutInflater.from(getContext()).inflate(layoutResId, this, false);
}

public int addFooterView(int layoutResId) {
return addFooterView(getLayoutView(layoutResId), -1, LinearLayout.VERTICAL);
}

public int addFooterView(View footer) {
return addFooterView(footer, -1, LinearLayout.VERTICAL);
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,77 +1,94 @@
package me.jingbin.library.config;
package me.jingbin.library.divider;

/**
* @author jingbin
/*
* Copyright 2019. Bin Jing (https://github.com/youlookwhat)
*
* 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.
*/

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;


/**
* 可以取消底部分割线的ItemDecoration
* copied from ByDividerItemDecoration
* mIsShowBottomDivider false 不显示底部分割线
* mIsShowFirstDivider false 不显示第一个item的分割线
* mIsShowSecondDivider false 不显示第二个item的分割线
* 可以去除头部尾部divider的ItemDecoration
*
* @author jingbin
* https://github.com/youlookwhat/ByRecyclerView
*/
public class ByDividerItemDecoration extends RecyclerView.ItemDecoration {
public class SpacesItemDecoration extends RecyclerView.ItemDecoration {

public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
public static final int VERTICAL = LinearLayout.VERTICAL;
private static final String TAG = "DividerItem";
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
private static final String TAG = "itemDivider";
private Drawable mDivider;
private boolean mIsShowBottomDivider;
private boolean mIsShowFirstDivider;
private boolean mIsShowSecondDivider;
private final Rect mBounds = new Rect();
private Context mContext;
/**
* 在AppTheme里配置 android:listDivider
*/
private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
/**
* 头部 不显示分割线的item个数
*/
private int mHeaderNoShowSize = 0;
/**
* 尾部 不显示分割线的item格式 默认不显示最后一个item的分割线
*/
private int mFooterNoShowSize = 1;
/**
* Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}.
*/
private int mOrientation;
private final Rect mBounds = new Rect();


public ByDividerItemDecoration(Context context, int orientation) {
this(context, orientation, false, true, true);
public SpacesItemDecoration(Context context, int orientation) {
this(context, orientation, 0, 1);
}

public ByDividerItemDecoration(Context context, int orientation, boolean isShowBottomDivider) {
this(context, orientation, isShowBottomDivider, true, true);
public SpacesItemDecoration(Context context, int orientation, int headerNoShowSize) {
this(context, orientation, headerNoShowSize, 1);
}

/**
* Creates a divider {@link RecyclerView.ItemDecoration} that can be used with a
* {@link android.support.v7.widget.LinearLayoutManager}.
* Creates a divider {@link RecyclerView.ItemDecoration}
*
* @param context Current context, it will be used to access resources.
* @param orientation Divider orientation. Should be {@link #HORIZONTAL} or
* {@link #VERTICAL}.
* @param isShowBottomDivider true show bottom divider false not show bottom divider
* @param context Current context, it will be used to access resources.
* @param orientation Divider orientation. Should be {@link #HORIZONTAL} or
* {@link #VERTICAL}.
* @param headerNoShowSize not show header divider size
* @param footerNoShowSize not show footer divider size
*/
public ByDividerItemDecoration(Context context, int orientation,
boolean isShowBottomDivider, boolean isShowFirstDivider, boolean isShowSecondDivider) {
mIsShowBottomDivider = isShowBottomDivider;
mIsShowFirstDivider = isShowFirstDivider;
mIsShowSecondDivider = isShowSecondDivider;

public SpacesItemDecoration(Context context, int orientation, int headerNoShowSize, int footerNoShowSize) {
mContext = context;
mHeaderNoShowSize = headerNoShowSize;
mFooterNoShowSize = footerNoShowSize;
setOrientation(orientation);
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
if (mDivider == null) {
Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this "
+ "ByDividerItemDecoration. Please set that attribute all call setDrawable()");
Log.w(TAG, "@android:attr/listDivider was not set in the theme used for this " + "SpacesItemDecoration. Please set that attribute all call setDrawable()");
}
a.recycle();
setOrientation(orientation);
}

/**
Expand All @@ -82,8 +99,7 @@ public ByDividerItemDecoration(Context context, int orientation,
*/
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL && orientation != VERTICAL) {
throw new IllegalArgumentException(
"Invalid orientation. It should be either HORIZONTAL or VERTICAL");
throw new IllegalArgumentException("Invalid orientation. It should be either HORIZONTAL or VERTICAL");
}
mOrientation = orientation;
}
Expand All @@ -95,20 +111,24 @@ public void setOrientation(int orientation) {
*/
public void setDrawable(Drawable drawable) {
if (drawable == null) {
throw new IllegalArgumentException("Drawable cannot be null.");
throw new IllegalArgumentException("drawable cannot be null.");
}
mDivider = drawable;
}

public void setDrawable(@DrawableRes int id) {
setDrawable(ContextCompat.getDrawable(mContext, id));
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
public void onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) {
if (parent.getLayoutManager() == null || mDivider == null) {
return;
}
if (mOrientation == VERTICAL) {
drawVertical(c, parent, state);
drawVertical(canvas, parent, state);
} else {
drawHorizontal(c, parent, state);
drawHorizontal(canvas, parent, state);
}
}

Expand All @@ -132,16 +152,13 @@ private void drawVertical(Canvas canvas, RecyclerView parent, RecyclerView.State
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final int childRealPosition = parent.getChildAdapterPosition(child);
// mIsShowFirstDivider false绘制第一个view的divider
if (childRealPosition == 0 && !mIsShowFirstDivider) {
continue;
}
// mIsShowSecondDivider false绘制第二个view的divider
if (childRealPosition == 1 && !mIsShowSecondDivider) {

// 过滤到头部不显示的分割线
if (childRealPosition < mHeaderNoShowSize) {
continue;
}
// mIsShowBottomDivider false的时候不绘制最后一个view的divider
if (mIsShowBottomDivider || childRealPosition < lastPosition) {
// 过滤到尾部不显示的分割线
if (childRealPosition <= lastPosition - mFooterNoShowSize) {
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(child.getTranslationY());
final int top = bottom - mDivider.getIntrinsicHeight();
Expand Down Expand Up @@ -172,17 +189,14 @@ private void drawHorizontal(Canvas canvas, RecyclerView parent, RecyclerView.Sta
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final int childRealPosition = parent.getChildAdapterPosition(child);
// mIsShowFirstDivider false绘制第一个view的divider
if (childRealPosition == 0 && !mIsShowFirstDivider) {
continue;
}
// mIsShowSecondDivider false绘制第二个view的divider
if (childRealPosition == 1 && !mIsShowSecondDivider) {

// 过滤到头部不显示的分割线
if (childRealPosition < mHeaderNoShowSize) {
continue;
}
//mIsShowBottomDivider false的时候不绘制最后一个view的divider
if (mIsShowBottomDivider || childRealPosition < lastPosition) {
parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds);
// 过滤到尾部不显示的分割线
if (childRealPosition <= lastPosition - mFooterNoShowSize) {
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int right = mBounds.right + Math.round(child.getTranslationX());
final int left = right - mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
Expand All @@ -193,31 +207,44 @@ private void drawHorizontal(Canvas canvas, RecyclerView parent, RecyclerView.Sta
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
if (mDivider == null) {
outRect.set(0, 0, 0, 0);
return;
}
if (mOrientation == VERTICAL) {
//parent.getChildCount() 不能拿到item的总数
//https://stackoverflow.com/questions/29666598/android-recyclerview-finding-out-first
// -and-last-view-on-itemdecoration
int lastPosition = state.getItemCount() - 1;
int position = parent.getChildAdapterPosition(view);
if (mIsShowBottomDivider || position < lastPosition) {
if (position <= lastPosition - mFooterNoShowSize) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else {
outRect.set(0, 0, 0, 0);
}
} else {
int lastPosition = state.getItemCount() - 1;
int position = parent.getChildAdapterPosition(view);
if (mIsShowBottomDivider || position < lastPosition) {
if (position <= lastPosition - mFooterNoShowSize) {
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
} else {
outRect.set(0, 0, 0, 0);
}
}
}

/**
* 设置不显示分割线的item位置
*
* @param headerNoShowSize 头部 不显示分割线的item个数
* @param footerNoShowSize 尾部 不显示分割线的item个数,默认1,不显示最后一个,最后一个一般为加载更多view
*/
public void setNoShowDivider(int headerNoShowSize, int footerNoShowSize) {
this.mHeaderNoShowSize = headerNoShowSize;
this.mFooterNoShowSize = footerNoShowSize;
}

public void setHeaderNoShowDivider(int headerNoShowSize) {
this.mHeaderNoShowSize = headerNoShowSize;
}

}

0 comments on commit 949c457

Please sign in to comment.