publicclassSectionDecorationextendsRecyclerView.ItemDecoration{
privatestaticfinalStringTAG="SectionDecoration";
privateListdataList;
privateDecorationCallbackcallback;
privateTextPainttextPaint;
privatePaintpaint;
privateinttopGap;
privateintalignBottom;
privatePaint.FontMetricsfontMetrics;
publicSectionDecoration(ListdataList,Contextcontext,DecorationCallbackdecorationCallback){
Resourcesres=context.getResources();
this.dataList=dataList;
this.callback=decorationCallback;
//设置悬浮栏的画笔---paint
paint=newPaint();
paint.setColor(res.getColor(R.color.colorGray));
//设置悬浮栏中文本的画笔
textPaint=newTextPaint();
textPaint.setAntiAlias(true);
textPaint.setTextSize(DensityUtil.dip2px(context,14));
textPaint.setColor(Color.DKGRAY);
textPaint.setTextAlign(Paint.Align.LEFT);
fontMetrics=newPaint.FontMetrics();
//决定悬浮栏的高度等
topGap=res.getDimensionPixelSize(R.dimen.sectioned_top);
//决定文本的显示位置等
alignBottom=res.getDimensionPixelSize(R.dimen.sectioned_alignBottom);
}
@Override
publicvoidgetItemOffsets(RectoutRect,Viewview,RecyclerViewparent,RecyclerView.Statestate){
super.getItemOffsets(outRect,view,parent,state);
intpos=parent.getChildAdapterPosition(view);
Log.i(TAG,"getItemOffsets:"+pos);
StringgroupId=callback.getGroupId(pos);
if(groupId.equals("-1"))return;
//只有是同一组的第一个才显示悬浮栏
if(pos==0||isFirstInGroup(pos)){
outRect.top=topGap;
if(dataList.get(pos).getName()==""){
outRect.top=0;
}
}else{
outRect.top=0;
}
}
@Override
publicvoidonDraw(Canvasc,RecyclerViewparent,RecyclerView.Statestate){
super.onDraw(c,parent,state);
intleft=parent.getPaddingLeft();
intright=parent.getWidth()-parent.getPaddingRight();
intchildCount=parent.getChildCount();
for(inti=0;i
Viewview=parent.getChildAt(i);
intposition=parent.getChildAdapterPosition(view);
StringgroupId=callback.getGroupId(position);
if(groupId.equals("-1"))return;
StringtextLine=callback.getGroupFirstLine(position).toUpperCase();
if(textLine==""){
floattop=view.getTop();
floatbottom=view.getTop();
c.drawRect(left,top,right,bottom,paint);
return;
}else{
if(position==0||isFirstInGroup(position)){
floattop=view.getTop()-topGap;
floatbottom=view.getTop();
//绘制悬浮栏
c.drawRect(left,top-topGap,right,bottom,paint);
//绘制文本
c.drawText(textLine,left,bottom,textPaint);
}
}
}
}
@Override
publicvoidonDrawOver(Canvasc,RecyclerViewparent,RecyclerView.Statestate){
super.onDrawOver(c,parent,state);
intitemCount=state.getItemCount();
intchildCount=parent.getChildCount();
intleft=parent.getPaddingLeft();
intright=parent.getWidth()-parent.getPaddingRight();
floatlineHeight=textPaint.getTextSize()+fontMetrics.descent;
StringpreGroupId="";
StringgroupId="-1";
for(inti=0;i
Viewview=parent.getChildAt(i);
intposition=parent.getChildAdapterPosition(view);
preGroupId=groupId;
groupId=callback.getGroupId(position);
if(groupId.equals("-1")||groupId.equals(preGroupId))continue;
StringtextLine=callback.getGroupFirstLine(position).toUpperCase();
if(TextUtils.isEmpty(textLine))continue;
intviewBottom=view.getBottom();
floattextY=Math.max(topGap,view.getTop());
//下一个和当前不一样移动当前
if(position+1
StringnextGroupId=callback.getGroupId(position+1);
//组内最后一个view进入了header
if(nextGroupId!=groupId&&viewBottom
textY=viewBottom;
}
}
//textY - topGap决定了悬浮栏绘制的高度和位置
c.drawRect(left,textY-topGap,right,textY,paint);
//left+2*alignBottom 决定了文本往左偏移的多少(加-->向左移)
//textY-alignBottom 决定了文本往右偏移的多少 (减-->向上移)
c.drawText(textLine,left+2*alignBottom,textY-alignBottom,textPaint);
}
}
/**
* 判断是不是组中的第一个位置
*
* @param pos
* @return
*/
privatebooleanisFirstInGroup(intpos){
if(pos==0){
returntrue;
}else{
// 因为是根据 字符串内容的相同与否 来判断是不是同意组的,所以此处的标记id 要是String类型
// 如果你只是做联系人列表,悬浮框里显示的只是一个字母,则标记id直接用 int 类型就行了
StringprevGroupId=callback.getGroupId(pos-1);
StringgroupId=callback.getGroupId(pos);
//判断前一个字符串 与 当前字符串 是否相同
if(prevGroupId.equals(groupId)){
returnfalse;
}else{
returntrue;
}
}
}
//定义一个借口方便外界的调用
interfaceDecorationCallback{
StringgetGroupId(intposition);
StringgetGroupFirstLine(intposition);
}
}