安卓吸顶+下拉放大_安卓当下最流行的吸顶效果的实现(下)

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);

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我可以提供一些思路和参考代码。 首先,实现 Android 中的自定义,可以采用两种方式: 1. 使用固定部控件 + ScrollView + ViewPager 的方式实现。 这种方式比较常见,具体实现思路如下: (1)在布局文件中定义一个固定在部的控件,例如 LinearLayout,将其设置为可见性为 gone,即不可见。 (2)在 ScrollView 中添加 ViewPager,将其填充满整个布局,用于滑动切换不同的子页面。 (3)监听 ScrollView 的滑动事件,在滑动到一定位置时,将部控件设置为可见,实现效果。 具体实现代码可以参考以下链接: - https://www.jianshu.com/p/4f28a4d0c3b1 - https://www.cnblogs.com/xiaohuafice/p/11050662.html 2. 使用 CoordinatorLayout + AppBarLayout 实现。 这种方式相对来说比较简单,具体实现思路如下: (1)在布局文件中使用 CoordinatorLayout 作为根布局,并添加一个 AppBarLayout 作为子布局。 (2)在 AppBarLayout 中添加一个 Toolbar 控件作为部的固定控件,将其设置为可见性为 gone。 (3)在子页面中,使用 NestedScrollView 作为滑动的容器,并将其放在 AppBarLayout 的下面。 (4)监听 NestedScrollView 的滑动事件,在滑动到一定位置时,将 Toolbar 设置为可见,实现效果。 具体实现代码可以参考以下链接: - https://www.jianshu.com/p/5d0f7e7e7c97 - https://www.jianshu.com/p/5d0f7e7e7c97 希望以上内容能够帮助到你,有什么问题可以再和我交流哦!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值