1. 程式人生 > >Android studio RecyclerView實現炫酷吸頂效果

Android studio RecyclerView實現炫酷吸頂效果

public class SectionDecoration extends RecyclerView.ItemDecoration {
    private List<NameBean> beanList;
    private TextPaint textPaint;
    private Paint paint;
    private int topGap;
    private int alignBottom;
    private DecorationCallback callback;
    private Paint.FontMetrics fontMetrics
; interface DecorationCallback{ String getGroupId(int position); String getGroupFirstLine(int position); } private boolean isFirstInGroup(int pos){ if (pos==0){ return true; }else { //因為是根據字串的內容的相同與否來判斷是不是同意組的,所以此處的標記id要是String型別 //如果只做聯絡人列表懸浮框裡面顯示的是字母則標記id直接用int型別就行了
String prevGroupId=callback.getGroupId(pos-1); String groupId=callback.getGroupId(pos); //判斷前一個字串與當前字串是否相同 if(prevGroupId.equals(groupId)){ return false; }else { return true; } } } public SectionDecoration(List<NameBean> beanList, Context context,
DecorationCallback callback ){ Resources resources=context.getResources(); this.beanList=beanList; this.callback=callback; //設定懸浮欄的畫筆 paint=new Paint(); paint.setColor(ContextCompat.getColor(context,R.color.colorPrimary)); //設定懸浮欄中文字的畫筆 textPaint=new TextPaint(); textPaint.setAntiAlias(true); textPaint.setTextSize(DensityUtil.dip2px(context,12)); textPaint.setTextAlign(Paint.Align.LEFT); textPaint.setColor(Color.WHITE); fontMetrics=new Paint.FontMetrics(); //決定懸浮欄的高度等 topGap=resources.getDimensionPixelSize(R.dimen.sectioned_top); //決定文字的顯示位置等 alignBottom=resources.getDimensionPixelSize(R.dimen.sectioned_alignBottom); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); int pos=parent.getChildAdapterPosition(view); String groupId=callback.getGroupId(pos); if (groupId.equals("-1"))return; //只有是同一組的第一個才顯示懸浮欄 if(pos==0 || isFirstInGroup(pos)){ outRect.top=topGap; if (beanList.get(pos).getName()==""){ outRect.top=0; } }else { outRect.top=0; } } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); int left=parent.getPaddingLeft(); int right=parent.getWidth()-parent.getPaddingRight(); int childCount=parent.getChildCount(); for (int i=0;i<childCount;i++){ View view=parent.getChildAt(i); int position=parent.getChildAdapterPosition(view); String groupId=callback.getGroupId(position); if (groupId.equals("-1"))return; String textLine=callback.getGroupFirstLine(position).toUpperCase(); if (textLine==""){ float top=view.getTop(); float bottom=view.getTop(); c.drawRect(left,top,right,bottom,paint); return; }else { if (position==0|| isFirstInGroup(position)){ float top=view.getTop()-topGap; float bottom=view.getTop(); //繪製懸浮欄 c.drawRect(left,top-topGap,right,bottom,paint); //繪製文字 c.drawText(textLine,left,bottom,textPaint); } } } } @Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDrawOver(c, parent, state); int itemCount=state.getItemCount(); int childCount=parent.getChildCount(); int left=parent.getPaddingLeft(); int right=parent.getWidth()-parent.getPaddingRight(); String preGroupId=""; String groupId="-1"; for (int i=0; i<childCount;i++){ View view=parent.getChildAt(i); int position=parent.getChildAdapterPosition(view); preGroupId=groupId; groupId=callback.getGroupId(position); if (groupId.equals("-1") || groupId.equals(preGroupId))continue; String textLine=callback.getGroupFirstLine(position).toUpperCase(); if (TextUtils.isEmpty(textLine))continue; int viewBottom=view.getBottom(); float textY=Math.max(topGap,view.getTop()); //下一個和當前不一樣移動當前 if (position+1<itemCount){ String nextGroupId=callback.getGroupId(position+1); //組內最後一個view進入了header if (nextGroupId!=groupId&&viewBottom<textY){ textY=viewBottom; } } //textY-toGap決定了懸浮欄繪製的高度和位置 c.drawRect(left,textY-topGap,right,textY,paint); //left+2*alignbottom決定了文字往右偏移的多少 c.drawText(textLine,left+2*alignBottom,textY-alignBottom,textPaint); } } }