Android RecyclerView 使用ItemDecoration 實現吸附效果
阿新 • • 發佈:2019-01-07
public class StickyItemDecoration extends RecyclerView.ItemDecoration { private ISticky mISticky; //矩形高度 private int mRectHeight; //文字TextSize private int mTextPaintSize; private Paint mTxtPaint; private Paint mRectPaint; //分割線畫筆 private Paint mDividerPaint; //手機狀態列的高度 private int mStatusBarHeight; public StickyItemDecoration(Context context, int statusBarHeight, ISticky iSticky) { mStatusBarHeight=statusBarHeight; mISticky=iSticky; mRectHeight= (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,30, context.getResources().getDisplayMetrics()); mTextPaintSize=(int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,17, context.getResources().getDisplayMetrics()); mTxtPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mTxtPaint.setColor(Color.BLACK); mTxtPaint.setTextSize(mTextPaintSize); mRectPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mRectPaint.setStyle(Paint.Style.FILL); mRectPaint.setColor(Color.parseColor("#DDDDDD")); mDividerPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mDividerPaint.setStyle(Paint.Style.FILL); mDividerPaint.setColor(Color.WHITE); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); int childCount=parent.getChildCount(); for (int i = 0; i < childCount; i++) { View view=parent.getChildAt(i); int left=parent.getPaddingLeft(); int right=parent.getWidth()-parent.getPaddingRight(); int top=view.getTop()-1; int bottom=view.getTop(); //Item分割線 c.drawRect(left,top,right,bottom,mDividerPaint); } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); int childCount=parent.getChildCount(); int itemCount=state.getItemCount(); int left=parent.getPaddingLeft(); int right=parent.getWidth()-parent.getPaddingRight(); String preGroupTitle; String groupTitle=""; for (int i = 0; i < childCount; i++) { View child=parent.getChildAt(i); int pos=parent.getChildLayoutPosition(child); preGroupTitle=groupTitle; groupTitle=mISticky.getGroupTitle(pos); //如果當前分組名和之前分組名一樣,忽略此次迴圈 if (groupTitle.equals(preGroupTitle)) { continue; } //文字的基線,保證顯示完全 int textBaseLine=Math.max(mRectHeight,child.getTop()); //分組標題 String title=mISticky.getGroupTitle(pos); int viewBottom=child.getBottom(); //加入限定 防止陣列越界 if (pos + 1 < itemCount) { String nextGroupTitle=mISticky.getGroupTitle(pos+1); //當分組不一樣 並且改組要向上移動時候 if (!nextGroupTitle.equals(groupTitle) && viewBottom < textBaseLine) { //將上一個往上移動 textBaseLine = viewBottom; } } //繪製邊框 c.drawRect(left, textBaseLine - mRectHeight, right, textBaseLine, mRectPaint); //繪製文字並且實現文字居中 int value= (int) Math.abs(mTxtPaint.getFontMetrics().descent +mTxtPaint.getFontMetrics().ascent); c.drawText(title, left, textBaseLine-(mRectHeight+value-mStatusBarHeight)/2, mTxtPaint); } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int pos=parent.getChildLayoutPosition(view); if (mISticky.isFirstPosition(pos)) { outRect.top=mRectHeight; outRect.bottom=1; }else { outRect.bottom=1; } } }