forked from huanghaibin-dev/CalendarView
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
329ef22
commit a0d9c84
Showing
14 changed files
with
695 additions
and
636 deletions.
There are no files selected for viewing
162 changes: 77 additions & 85 deletions
162
app/src/main/java/com/haibin/calendarviewproject/ArticleAdapter.java
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
277 changes: 277 additions & 0 deletions
277
app/src/main/java/com/haibin/calendarviewproject/group/GroupItemDecoration.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
package com.haibin.calendarviewproject.group; | ||
|
||
import android.annotation.SuppressLint; | ||
import android.graphics.Canvas; | ||
import android.graphics.Paint; | ||
import android.graphics.Rect; | ||
import android.support.v7.widget.LinearLayoutManager; | ||
import android.support.v7.widget.RecyclerView; | ||
import android.text.TextUtils; | ||
import android.view.View; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* 分组浮动的ItemDecoration | ||
* Created by haibin on 2017/5/15. | ||
*/ | ||
@SuppressWarnings("all") | ||
public class GroupItemDecoration<Group, Child> extends RecyclerView.ItemDecoration { | ||
protected int mGroupHeight; | ||
protected int mGroutBackground; | ||
protected Paint mBackgroundPaint; | ||
protected Paint mTextPaint; | ||
protected float mTextBaseLine; | ||
protected int mPaddingLeft, mPaddingRight; | ||
protected boolean isCenter; | ||
protected boolean isHasHeader; | ||
@SuppressLint("UseSparseArrays") | ||
protected Map<Integer, Group> mGroup = new HashMap<>(); | ||
|
||
public GroupItemDecoration() { | ||
super(); | ||
init(); | ||
} | ||
|
||
private void init() { | ||
mBackgroundPaint = new Paint(); | ||
mBackgroundPaint.setColor(0xFFf5f7f8); | ||
mBackgroundPaint.setStyle(Paint.Style.FILL); | ||
mBackgroundPaint.setAntiAlias(true); | ||
|
||
mTextPaint = new Paint(); | ||
mTextPaint.setColor(0xFF353535); | ||
mTextPaint.setAntiAlias(true); | ||
} | ||
|
||
/** | ||
* 先于RecyclerView的Item onDraw调用 | ||
* | ||
* @param c RecyclerView canvas | ||
* @param parent RecyclerView | ||
* @param state stare | ||
*/ | ||
@Override | ||
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { | ||
super.onDraw(c, parent, state); | ||
onDrawGroup(c, parent); | ||
} | ||
|
||
/** | ||
* 绘制分组Group | ||
* | ||
* @param c Canvas | ||
* @param parent RecyclerView | ||
*/ | ||
protected void onDrawGroup(Canvas c, RecyclerView parent) { | ||
int paddingLeft = parent.getPaddingLeft(); | ||
int right = parent.getWidth() - parent.getPaddingRight(); | ||
int top, bottom; | ||
int count = parent.getChildCount(); | ||
for (int i = 0; i < parent.getChildCount(); i++) { | ||
View child = parent.getChildAt(i); | ||
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); | ||
int key = params.getViewLayoutPosition(); | ||
if (mGroup.containsKey(key)) { | ||
top = child.getTop() - params.topMargin - mGroupHeight; | ||
bottom = top + mGroupHeight; | ||
c.drawRect(paddingLeft, top, right, bottom, mBackgroundPaint); | ||
String group = mGroup.get(params.getViewLayoutPosition()).toString(); | ||
float x; | ||
float y = top + mTextBaseLine; | ||
if (isCenter) { | ||
x = parent.getMeasuredWidth() / 2 - getTextX(group); | ||
} else { | ||
x = mPaddingLeft; | ||
} | ||
c.drawText(group, x, y, mTextPaint); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* 后于RecyclerView的Item onDraw调用 | ||
* | ||
* @param c RecyclerView canvas | ||
* @param parent RecyclerView | ||
* @param state stare | ||
*/ | ||
@Override | ||
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { | ||
super.onDrawOver(c, parent, state); | ||
onDrawOverGroup(c, parent); | ||
} | ||
|
||
/** | ||
* 绘制悬浮组 | ||
* | ||
* @param c Canvas | ||
* @param parent RecyclerView | ||
*/ | ||
protected void onDrawOverGroup(Canvas c, RecyclerView parent) { | ||
int firstVisiblePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition(); | ||
if (firstVisiblePosition == RecyclerView.NO_POSITION) { | ||
return; | ||
} | ||
Group group = getCroup(firstVisiblePosition); | ||
if (group == null) | ||
return; | ||
String groupTitle = group.toString(); | ||
if (TextUtils.isEmpty(groupTitle)) { | ||
return; | ||
} | ||
boolean isRestore = false; | ||
Group nextGroup = getCroup(firstVisiblePosition + 1); | ||
if (nextGroup != null && !group.equals(nextGroup)) { | ||
//说明是当前组最后一个元素,但不一定碰撞了 | ||
View child = parent.findViewHolderForAdapterPosition(firstVisiblePosition).itemView; | ||
if (child.getTop() + child.getMeasuredHeight() < mGroupHeight) { | ||
//进一步检测碰撞 | ||
c.save();//保存画布当前的状态 | ||
isRestore = true; | ||
c.translate(0, child.getTop() + child.getMeasuredHeight() - mGroupHeight); | ||
} | ||
} | ||
int left = parent.getPaddingLeft(); | ||
int right = parent.getWidth() - parent.getPaddingRight(); | ||
int top = parent.getPaddingTop(); | ||
int bottom = top + mGroupHeight; | ||
c.drawRect(left, top, right, bottom, mBackgroundPaint); | ||
float x; | ||
float y = top + mTextBaseLine; | ||
if (isCenter) { | ||
x = parent.getMeasuredWidth() / 2 - getTextX(groupTitle); | ||
} else { | ||
x = mPaddingLeft; | ||
} | ||
c.drawText(groupTitle, x, y, mTextPaint); | ||
if (isRestore) { | ||
//还原画布为初始状态 | ||
c.restore(); | ||
} | ||
} | ||
|
||
/** | ||
* 设置item的上下左右偏移量 | ||
* | ||
* @param outRect rect | ||
* @param view item | ||
* @param parent RecyclerView | ||
* @param state stare | ||
*/ | ||
@Override | ||
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { | ||
super.getItemOffsets(outRect, view, parent, state); | ||
getItemOffsets(outRect, view, parent, parent.getChildViewHolder(view).getAdapterPosition()); | ||
} | ||
|
||
/** | ||
* 设置item的上下左右偏移量,不做任何处理就是默认状态 | ||
* | ||
* @param outRect outRect | ||
* @param view view | ||
* @param parent RecyclerView | ||
* @param adapterPosition position | ||
*/ | ||
protected void getItemOffsets(Rect outRect, View view, RecyclerView parent, int adapterPosition) { | ||
if (mGroup.containsKey(adapterPosition)) { | ||
outRect.set(0, mGroupHeight, 0, mGroup.containsKey(adapterPosition + 1) ? 0 : 20); | ||
} else { | ||
outRect.set(0, 0, 0, mGroup.containsKey(adapterPosition + 1) ? 0 : 20); | ||
} | ||
} | ||
|
||
/** | ||
* 获得当前ViewPosition所在的组 | ||
* | ||
* @param position 当前View的position | ||
* @return 当前ViewPosition所在的组 | ||
*/ | ||
protected Group getCroup(int position) { | ||
while (position >= 0) { | ||
if (mGroup.containsKey(position)) { | ||
return mGroup.get(position); | ||
} | ||
position--; | ||
} | ||
return null; | ||
} | ||
|
||
/** | ||
* 通知更新分组信息 | ||
* | ||
* @param adapter GroupRecyclerAdapter | ||
*/ | ||
public void notifyDataSetChanged(GroupRecyclerAdapter<Group, Child> adapter) { | ||
mGroup.clear(); | ||
if (adapter == null) return; | ||
int key = 0; | ||
for (int i = 0; i < adapter.getGroupCount(); i++) { | ||
if (i == 0) { | ||
mGroup.put(isHasHeader ? 1 : 0, adapter.getGroup(i)); | ||
key += adapter.getChildCount(i) + (isHasHeader ? 1 : 0); | ||
; | ||
} else { | ||
mGroup.put(key, adapter.getGroup(i)); | ||
key += adapter.getChildCount(i); | ||
} | ||
} | ||
} | ||
|
||
public void setBackground(int groupBackground) { | ||
mBackgroundPaint.setColor(groupBackground); | ||
} | ||
|
||
public void setTextColor(int textColor) { | ||
mTextPaint.setColor(textColor); | ||
} | ||
|
||
public void setTextSize(float textSize) { | ||
mTextPaint.setTextSize(textSize); | ||
Paint.FontMetrics metrics = mTextPaint.getFontMetrics(); | ||
mTextBaseLine = mGroupHeight / 2 - metrics.descent + (metrics.bottom - metrics.top) / 2; | ||
} | ||
|
||
public void setGroupHeight(int groupHeight) { | ||
mGroupHeight = groupHeight; | ||
Paint.FontMetrics metrics = mTextPaint.getFontMetrics(); | ||
mTextBaseLine = mGroupHeight / 2 - metrics.descent + (metrics.bottom - metrics.top) / 2; | ||
} | ||
|
||
public void setPadding(int mPaddingLeft, int mPaddingRight) { | ||
this.mPaddingLeft = mPaddingLeft; | ||
this.mPaddingRight = mPaddingRight; | ||
} | ||
|
||
public void setCenter(boolean isCenter) { | ||
this.isCenter = isCenter; | ||
} | ||
|
||
public void setHasHeader(boolean hasHeader) { | ||
isHasHeader = hasHeader; | ||
} | ||
|
||
/** | ||
* 获取文本的x坐标起点 | ||
* | ||
* @param str 文本 | ||
* @return x | ||
*/ | ||
protected float getTextX(String str) { | ||
Rect bounds = new Rect(); | ||
mTextPaint.getTextBounds(str, 0, str.length(), bounds); | ||
return bounds.width() / 2; | ||
} | ||
|
||
/** | ||
* 获取文本的长度像素 | ||
* @param str 文本 | ||
* @return px | ||
*/ | ||
protected float getTextLenghtPx(String str) { | ||
Rect bounds = new Rect(); | ||
mTextPaint.getTextBounds(str, 0, str.length(), bounds); | ||
return bounds.width(); | ||
} | ||
} |
Oops, something went wrong.