1. 程式人生 > >使用ItemDecoration為RecyclerView打造帶懸停頭部的分組列表

使用ItemDecoration為RecyclerView打造帶懸停頭部的分組列表

package jiuyuhulian.com.merchantstoreApp.view;

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.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.TypedValue; import android.view.View; import java.util.List; import jiuyuhulian.com.merchantstoreApp.entity.ExchageDetailEntity; /** * 有分類title的 ItemDecoration * Created by Admin on 2017/3/31. */ public class TitleItemDecoration extends RecyclerView.ItemDecoration { private
List<ExchageDetailEntity> mDatas; 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字型大小 public TitleItemDecoration(Context context, List<ExchageDetailEntity> datas) { super(); mDatas = datas; 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); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); final int left = parent.getPaddingLeft(); final int right = parent.getWidth() - parent.getPaddingRight(); final int childCount = parent.getChildCount(); 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(); //我記得Rv的item position在重置時可能為-1.保險點判斷一下吧 if (position > -1) { if (position == 0) {//等於0肯定要有title的 drawTitleArea(c, left, right, child, params, position); } else {//其他的通過判斷 if (null != mDatas.get(position).getMouth() && !mDatas.get(position).getMouth().equals(mDatas.get(position - 1).getMouth())) { //不為空 且跟前一個tag不一樣了,說明是新的分類,也要title drawTitleArea(c, left, right, child, params, position); } else { //none } } } } } /** * 繪製Title區域背景和文字的方法 * * @param c * @param left * @param right * @param child * @param params * @param position */ private void drawTitleArea(Canvas c, int left, int right, View child, RecyclerView.LayoutParams params, int position) {//最先呼叫,繪製在最下層 mPaint.setColor(COLOR_TITLE_BG); c.drawRect(left, child.getTop() - params.topMargin - mTitleHeight, right, child.getTop() - params.topMargin, mPaint); mPaint.setColor(COLOR_TITLE_FONT); /* Paint.FontMetricsInt fontMetrics = mPaint.getFontMetricsInt(); int baseline = (getMeasuredHeight() - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;*/ mPaint.getTextBounds(mDatas.get(position).getMouth(), 0, mDatas.get(position).getMouth().length(), mBounds); c.drawText(mDatas.get(position).getMouth(), child.getPaddingLeft(), child.getTop() - params.topMargin - (mTitleHeight / 2 - mBounds.height() / 2), mPaint); } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {//最後呼叫 繪製在最上層 int pos = ((LinearLayoutManager)(parent.getLayoutManager())).findFirstVisibleItemPosition(); String tag = mDatas.get(pos).getMouth(); //View child = parent.getChildAt(pos); View child = parent.findViewHolderForLayoutPosition(pos).itemView;//出現一個奇怪的bug,有時候child為空,所以將 child = parent.getChildAt(i)。-》 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(tag, 0, tag.length(), mBounds); c.drawText(tag, child.getPaddingLeft(), parent.getPaddingTop() + mTitleHeight - (mTitleHeight / 2 - mBounds.height() / 2), mPaint); } @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(); //我記得Rv的item position在重置時可能為-1.保險點判斷一下吧 if (position > -1) { if (position == 0) {//等於0肯定要有title的 outRect.set(0, mTitleHeight, 0, 0); } else {//其他的通過判斷 if (null != mDatas.get(position).getMouth() && !mDatas.get(position).getMouth().equals(mDatas.get(position - 1).getMouth())) { outRect.set(0, mTitleHeight, 0, 0);//不為空 且跟前一個tag不一樣了,說明是新的分類,也要title } else { outRect.set(0, 0, 0, 0); } } } } }