转载请注明出处:
http://blog.csdn.net/user11223344abc?viewmode=contents
出自【蛟-blog】
0.介绍
0.1:先看下效果图吧。
请无视titleBar,用之前的一个项目改的,懒得新建了,嘻嘻 :P
1.本文的数据格式
{
"msg": "",
"code": 0,
"data": [
{
"key": "a",
"items": [
{
"area": null,
"mbile": 1499256758000
}
]
},
{
"key": "d",
"items": [
{
"area": null,
"mbile": 1499256758000
},
{
"area": null,
"mbile": 1499256758000
}
]
}
]
}
2.本文的代码结构
标出来的就是这次我们要讨论的核心。ItemDirection
ItemDirection是RecyclerView的分割线,这个属于它的一个扩展功能。
3.基本思路
我们抛开代码,用正常的逻辑来思考,是不是应该做如下3步的考虑:
3.1.找出位置
一个很重要的问题就是找出边界值的问题。试想一下,我们把一堆数据源设置进了RecyclerView,看起来就跟以前的ListView一模一样,我们要插进分割线,那么每个分割线该放在什么位置?
再回头看下我的数据格式,发现就是一个关键字拖一堆的电话号码。
也就是许多个带了标识的集合。
实际上这个分割线的位置就是每个集合的size。
(还有一种是通过一个last标识来得出边界值,但是我这里数据已经分好了就不必那么麻烦了)
3.2.在该空间内画出分类信息
自定义View。
3.3.悬浮处理
自定义View。
4.代码理解:初始化,以及三个方法
4.1:初始化的代码。
private Paint mPaint;
private Rect mBounds;//用于存放测量文字Rect
private int mTitleHeight;//title的高
private static int COLOR_TITLE_BG = Color.parseColor("#FFDFDFDF");
private static int COLOR_TITLE_FONT = Color.parseColor("#FF000000");
private static int mTitleFontSize;//title字体大小
HashMap<Integer, String> keyPostMap = new HashMap<>();
private String mKeyOnDrawOver = "";
public StickyItemDirection(Context context, List<HotPhoneBean.DataBean> datas) {
super();
mPaint = new Paint();
mBounds = new Rect();
mTitleHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 30, context.getResources().getDisplayMetrics());
mTitleFontSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, context.getResources().getDisplayMetrics());
mPaint.setTextSize(mTitleFontSize);
mPaint.setAntiAlias(true);
HotPhoneBean.DataBean data0 = datas.get(0);
keyPostMap.put(0, data0.getKey());
for (int i = 0; i < datas.size(); i++) {
HotPhoneBean.DataBean dataBean = datas.get(i);
keyPostMap.put(dataBean.getItems().size(), dataBean.getKey());
}
}
4.2:找地,getItemOffsets()
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
int position = ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition();
ArrayList<Integer> posList = new ArrayList<>(keyPostMap.keySet());
if (position > -1) {
if (posList.contains(position)) {
outRect.set(0, mTitleHeight, 0, 0);
} else {
outRect.set(0, 0, 0, 0);
}
}
}
4.3:画字,onDraw()
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
Log.e("zj", "onDraw");
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
ArrayList<Integer> posList = new ArrayList<>(keyPostMap.keySet());
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
int position = params.getViewLayoutPosition();
if (position > -1) {
if (posList.contains(position)) {
String key = keyPostMap.get(position);
//drawing
mPaint.setColor(COLOR_TITLE_BG);
c.drawRect(left, child.getTop() - params.topMargin - mTitleHeight, right, child.getTop() - params.topMargin, mPaint);
mPaint.setColor(COLOR_TITLE_FONT);
mPaint.getTextBounds(key, 0, key.length(), mBounds);
c.drawText(key, child.getPaddingLeft(), child.getTop() - params.topMargin - (mTitleHeight / 2 - mBounds.height() / 2), mPaint);
}
}
}
}
4.4:悬浮,onDrawOver()
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {//最后调用 绘制在最上层
int pos = ((LinearLayoutManager) (parent.getLayoutManager())).findFirstVisibleItemPosition();
ArrayList<Integer> posList = new ArrayList<>(keyPostMap.keySet());
if (posList.contains(pos)) {
mKeyOnDrawOver = keyPostMap.get(pos);
}
View child = parent.findViewHolderForLayoutPosition(pos).itemView;
parent.findViewHolderForLayoutPosition(pos).itemView
mPaint.setColor(COLOR_TITLE_BG);
c.drawRect(parent.getPaddingLeft(), parent.getPaddingTop(), parent.getRight() - parent.getPaddingRight(), parent.getPaddingTop() + mTitleHeight, mPaint);
mPaint.setColor(COLOR_TITLE_FONT);
mPaint.getTextBounds(mKeyOnDrawOver, 0, mKeyOnDrawOver.length(), mBounds);
c.drawText(mKeyOnDrawOver, child.getPaddingLeft(),
parent.getPaddingTop() + mTitleHeight - (mTitleHeight / 2 - mBounds.height() / 2),
mPaint);
}
5.本文的Demo下载:
有什么问题请留言,有错误还望指出,感谢。
点击下载