package com.example.dq.app_itemdecoration;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.text.TextPaint;
import android.text.TextUtils;
import android.view.View;
/**
* Created by DQ on 2017/8/7
* 城市列表的分割线, 主要用于绘制字母分组
*/
public class CityItemDecoration extends RecyclerView.ItemDecoration {
private int mGroupHeight = 60;
private int mSideMargin = 10;
private Paint mGroupPaint;
private TextPaint mTextPaint;
private GroupListener mListener;
public CityItemDecoration(Context context, GroupListener pListener) {
mGroupPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mGroupPaint.setColor(context.getResources().getColor(android.R.color.holo_blue_dark));
mListener = pListener;
mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
mTextPaint.setTextSize(40);
mTextPaint.setColor(Color.WHITE);
mTextPaint.setTextAlign(Paint.Align.LEFT);
}
// 偏移距离,可以变相的理解成,分割线的高度
@Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = parent.getChildAdapterPosition(view);
// 不是省份
if (mListener == null || TextUtils.isEmpty(mListener.getGroupName(position))) {
return;
}
// 是否显示 省份标签
if (isFirstInGroup(position)) {
outRect.top = mGroupHeight;
}
}
@Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDrawOver(c, parent, state);
final int itemCount = state.getItemCount();
final int childCount = parent.getChildCount();
final int left = parent.getLeft() + parent.getPaddingLeft();
final int right = parent.getRight() + parent.getPaddingRight();
String preGroupName; // 标记上一个item的省份
String currentGroupName = null; // 当前item的省份
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);
int position = parent.getChildAdapterPosition(child);
preGroupName = currentGroupName;
currentGroupName = mListener.getGroupName(position);
// 普通城市 or 和上一次省份相同
if (TextUtils.equals(currentGroupName, preGroupName)) {
continue;
}
// 计算高度
int bottom = Math.max(mGroupHeight, child.getTop());
if (position < itemCount - 1) {
String nextGroupName = mListener.getGroupName(position + 1);
int viewBottom = child.getBottom();
if (!currentGroupName.equals(nextGroupName) && viewBottom < bottom) {
bottom = viewBottom;
}
}
// 接下来, 就是省份的绘制了
c.drawRect(left, bottom - mGroupHeight, right, bottom, mGroupPaint);
// 绘制文字
Paint.FontMetrics fm = mTextPaint.getFontMetrics();
float baseline = bottom - (mGroupHeight - (fm.bottom - fm.top)) / 2 - fm.bottom;
// TODO: 2017/8/7 DQ: 这里添加的是左右边距,是可以自己设置的
float textWidth = mTextPaint.measureText(currentGroupName);
float marginLeft = true ? 0 : right - textWidth;
mSideMargin = Math.abs(mSideMargin);
mSideMargin = true ? mSideMargin : -mSideMargin;
c.drawText(currentGroupName, left + mSideMargin + marginLeft, baseline, mTextPaint);
}
}
public interface GroupListener {
String getGroupName(int position);
}
private boolean isFirstInGroup(int position) {
if (position == 0) {
return true;
} else {
String prevGroupId = mListener.getGroupName(position - 1);
String groupId = mListener.getGroupName(position);
return !TextUtils.equals(prevGroupId, groupId);
}
}
}
[Android] 零碎知识汇总 - RecyclerView 顶部悬浮
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 用这个方式实现有很大的局限性, 粗糙的解释一下, 在recyclerView上套一层和itemView 上一样的h...
- 之前的项目中有需要开发一个悬浮置顶的效果,今天看到一篇文章,也是讲到这么一个效果,但是实现方法不同,明显比自己的更...
- 利用RecyclerView.ItemDecoration实现的悬浮效果 getItemOffsets:通过Rec...
- 上图: 本文代码的Github地址 思路: 每一个RecyclerView的item的布局(下文叫itemUI...
- 12月5日下午,机关七支部全体党员及入党积极分子参加了以“宪法宣传活动”为主题的主题党日活动。此次活动特邀...