安卓当下最流行的吸顶效果的实现(下)

接上文

第一步:首先我们来写一个类,它起标记的作用,来放每一个item的对应的悬浮栏的字符串


  1. public class NameBean {   
  2.     String name;   
  3.    
  4.     public String getName() {   
  5.         return name;   
  6.     }   
  7.    
  8.     public void setName(String name) {   
  9.         this.name = name;   
  10.     }   

第二步:自定义一个SectionDecoration 类 继承 RecyclerView的ItemDecoration


  1. public class SectionDecoration extends RecyclerView.ItemDecoration {   
  2.     private static final String TAG = "SectionDecoration";   
  3.    
  4.     private List<NameBean> dataList;   
  5.    
  6.     private DecorationCallback callback;   
  7.     private TextPaint textPaint;   
  8.     private Paint paint;   
  9.     private int topGap;   
  10.     private int alignBottom;   
  11.     private Paint.FontMetrics fontMetrics;   
  12.    
  13.    
  14.     public SectionDecoration(List<NameBean> dataList, Context context, DecorationCallback decorationCallback) {   
  15.         Resources res = context.getResources();   
  16.         this.dataList = dataList;   
  17.         this.callback = decorationCallback;   
  18.         //设置悬浮栏的画笔---paint   
  19.         paint = new Paint();   
  20.         paint.setColor(res.getColor(R.color.colorGray));   
  21.    
  22.         //设置悬浮栏中文本的画笔   
  23.         textPaint = new TextPaint();   
  24.         textPaint.setAntiAlias(true);   
  25.         textPaint.setTextSize(DensityUtil.dip2px(context, 14));   
  26.         textPaint.setColor(Color.DKGRAY);   
  27.         textPaint.setTextAlign(Paint.Align.LEFT);   
  28.         fontMetrics = new Paint.FontMetrics();   
  29.         //决定悬浮栏的高度等   
  30.         topGap = res.getDimensionPixelSize(R.dimen.sectioned_top);   
  31.         //决定文本的显示位置等   
  32.         alignBottom = res.getDimensionPixelSize(R.dimen.sectioned_alignBottom);   
  33.     }   
  34.    
  35.     @Override   
  36.     public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {   
  37.         super.getItemOffsets(outRect, view, parent, state);   
  38.         int pos = parent.getChildAdapterPosition(view);   
  39.         Log.i(TAG, "getItemOffsets:" + pos);   
  40.         String groupId = callback.getGroupId(pos);   
  41.         if (groupId.equals("-1")) return;   
  42.         //只有是同一组的第一个才显示悬浮栏   
  43.         if (pos == 0 || isFirstInGroup(pos)) {   
  44.             outRect.top = topGap;   
  45.             if (dataList.get(pos).getName() == "") {   
  46.                 outRect.top = 0;   
  47.             }   
  48.         } else {   
  49.             outRect.top = 0;   
  50.         }   
  51.     }   
  52.    
  53.     @Override   
  54.     public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {   
  55.         super.onDraw(c, parent, state);   
  56.         int left = parent.getPaddingLeft();   
  57.         int right = parent.getWidth() - parent.getPaddingRight();   
  58.         int childCount = parent.getChildCount();   
  59.         for (int i = 0; i < childCount; i++) {   
  60.             View view = parent.getChildAt(i);   
  61.             int position = parent.getChildAdapterPosition(view);   
  62.             String groupId = callback.getGroupId(position);   
  63.             if (groupId.equals("-1")) return;   
  64.             String textLine = callback.getGroupFirstLine(position).toUpperCase();   
  65.             if (textLine == "") {   
  66.                 float top = view.getTop();   
  67.                 float bottom = view.getTop();   
  68.                 c.drawRect(left, top, right, bottom, paint);   
  69.                 return;   
  70.             } else {   
  71.                 if (position == 0 || isFirstInGroup(position)) {   
  72.                     float top = view.getTop() - topGap;   
  73.                     float bottom = view.getTop();   
  74.                     //绘制悬浮栏   
  75.                     c.drawRect(left, top - topGap, right, bottom, paint);   
  76.                     //绘制文本   
  77.                     c.drawText(textLine, left, bottom, textPaint);   
  78.                 }   
  79.             }   
  80.         }   
  81.     }   
  82.    
  83.     @Override   
  84.     public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {   
  85.         super.onDrawOver(c, parent, state);   
  86.         int itemCount = state.getItemCount();   
  87.         int childCount = parent.getChildCount();   
  88.         int left = parent.getPaddingLeft();   
  89.         int right = parent.getWidth() - parent.getPaddingRight();   
  90.         float lineHeight = textPaint.getTextSize() + fontMetrics.descent;   
  91.    
  92.         String preGroupId = "";   
  93.         String groupId = "-1";   
  94.         for (int i = 0; i < childCount; i++) {   
  95.             View view = parent.getChildAt(i);   
  96.             int position = parent.getChildAdapterPosition(view);   
  97.    
  98.             preGroupId = groupId;   
  99.             groupId = callback.getGroupId(position);   
  100.             if (groupId.equals("-1") || groupId.equals(preGroupId)) continue;   
  101.    
  102.             String textLine = callback.getGroupFirstLine(position).toUpperCase();   
  103.             if (TextUtils.isEmpty(textLine)) continue;   
  104.    
  105.             int viewBottom = view.getBottom();   
  106.             float textY = Math.max(topGap, view.getTop());   
  107.             //下一个和当前不一样移动当前   
  108.             if (position + 1 < itemCount) {   
  109.                 String nextGroupId = callback.getGroupId(position + 1);   
  110.                 //组内最后一个view进入了header   
  111.                 if (nextGroupId != groupId && viewBottom < textY) {   
  112.                     textY = viewBottom;   
  113.                 }   
  114.             }   
  115.             //textY - topGap决定了悬浮栏绘制的高度和位置   
  116.             c.drawRect(left, textY - topGap, right, textY, paint);   
  117.             //left+2*alignBottom 决定了文本往左偏移的多少(加-->向左移)   
  118.             //textY-alignBottom  决定了文本往右偏移的多少  (减-->向上移)   
  119.             c.drawText(textLine, left + 2 * alignBottom, textY - alignBottom, textPaint);   
  120.         }   
  121.     }   
  122.    
  123.    
  124.     /** 
  125.      * 判断是不是组中的第一个位置 
  126.      * 
  127.      * @param pos 
  128.      * @return 
  129.      */   
  130.     private boolean isFirstInGroup(int pos) {   
  131.         if (pos == 0) {   
  132.             return true;   
  133.         } else {   
  134.             // 因为是根据 字符串内容的相同与否 来判断是不是同意组的,所以此处的标记id 要是String类型   
  135.             // 如果你只是做联系人列表,悬浮框里显示的只是一个字母,则标记id直接用 int 类型就行了   
  136.             String prevGroupId = callback.getGroupId(pos - 1);   
  137.             String groupId = callback.getGroupId(pos);   
  138.             //判断前一个字符串 与 当前字符串 是否相同   
  139.             if (prevGroupId.equals(groupId)) {   
  140.                 return false;   
  141.             } else {   
  142.                 return true;   
  143.             }   
  144.         }   
  145.     }   
  146.    
  147.     //定义一个借口方便外界的调用   
  148.     interface DecorationCallback {   
  149.         String getGroupId(int position);   
  150.    
  151.         String getGroupFirstLine(int position);   
  152.     }   

第三步:在向list集合中先把每一个item的 起“标记”作用的字符串都加进去


  1. setPullAction(comingslist); 

  1. private void setPullAction(List<WaitMVBean.DataBean.ComingBean> comingslist) {   
  2.         dataList = new ArrayList<>();   
  3.    
  4.         for (int i = 0; i < comingslist.size(); i++) {   
  5.             NameBean nameBean = new NameBean();   
  6.             String name0 = comingslist.get(i).getComingTitle();   
  7.             nameBean.setName(name0);   
  8.             dataList.add(nameBean);   
  9.         }   
  10.     } 

第四步:在setAdapter() 前,为RecyclerView添加ItemDecoration:


  1. recyclerView.addItemDecoration(new SectionDecoration(dataList,mContext, new SectionDecoration.DecorationCallback() {   
  2.                //返回标记id (即每一项对应的标志性的字符串)   
  3.                 @Override   
  4.                 public String getGroupId(int position) {   
  5.                     if(dataList.get(position).getName()!=null) {   
  6.                         return dataList.get(position).getName();   
  7.                     }   
  8.                     return "-1";   
  9.                 }   
  10.    
  11.                 //获取同组中的第一个内容   
  12.                 @Override   
  13.                 public String getGroupFirstLine(int position) {   
  14.                     if(dataList.get(position).getName()!=null) {   
  15.                         return dataList.get(position).getName();   
  16.                     }   
  17.                     return "";   
  18.                 }   
  19.             })); 

这样就完成了~

再看一眼最终效果感受一下:

本文作者:佚名

来源:51CTO

时间: 2024-08-18 02:55:49

安卓当下最流行的吸顶效果的实现(下)的相关文章

安卓当下最流行的吸顶效果的实现(上)

开始逐渐领略到ItemDecoration的美~ 今天让我 使用 ItemDecoration 来完成 可推动的悬浮导航栏的效果,最终实现的效果如下图: 具体实现步骤如下: 根据我前面的文章所讲的RecyclerView的基本使用,我们先来完成基本的recyclerView: 第一步:布局里写一个RecyclerView 第二步:实例化 recyclerView = (RecyclerView) findViewById(R.id.recyclerView);  第三步:获取所需的数据 (这里我

android中RecyclerView悬浮吸顶效果

MultiType-Adapter打造悬浮吸顶效果 注:当前版本只适合配合RecyclerView快速打造一款 展示UI 悬浮吸顶效果,如 通讯录效果,由于实现机制的原因,暂时不支持触摸事件. MultiType-Adapter介绍地址:MultiType-Adapter 是一款轻量级支持多数据类型的 RecyclerView 适配器; 使用简单,完全解耦; 悬浮吸顶效果 ```groovy // root build.gradle repositories { jcenter() maven

RecyclerVIew实现悬浮吸顶效果

RecyclerVIew实现悬浮吸顶效果图 这里写图片描述 主页面布局 <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height=&

当下最流行的Java报表工具是什么----------------------在线等

问题描述 当下最流行的Java制作报表的工具是什么,有没有大致介绍? 解决方案 解决方案二:顶,没有高手来解答吗?解决方案三:ajax插件解决方案四:引用2楼songsong_love的回复: ajax插件 这个能制作报表?解决方案五:highchart.js解决方案六:fusioncharts解决方案七:IBM的cognos,里面有所有图表,不过有点小贵,很好用解决方案八: 解决方案九:report-online.jar解决方案十:润乾也不错...解决方案十一:您可以自己写报表...解决方案十

吸顶大法 -- UWP中的工具栏吸顶的实现方式之一

原文:吸顶大法 -- UWP中的工具栏吸顶的实现方式之一 如果一个页面中有很长的列表/内容,很多应用都会在用户向下滚动时隐藏页面的头,给用户留出更多的阅读空间,同时提供一个方便的吸顶工具栏,比如淘宝中的店铺页面. 下面是一个比较简单的实现,如果有同学有更好的实现,欢迎留言,让我们共同进步. 首先假设我们的页面整体包含3部分;     页面头:随页面滚动慢慢消失/重现     工具栏: 开始时随页面滚动,在页面头消失后,吸顶,固定不动     可滚动内容:一个listview 结构代码如下,为了区

jQuery实现表格行上下移动和置顶效果

  本文给大家分享的是一款由jQuery实现的表格行上下移动以及置顶效果的代码,非常的简单实用,这里给出了核心代码,有需要的小伙伴可以参考下. 我们在操作列表数据的时候,需要将数据行排列顺序进行调整,如上移和下移行,将行数据置顶等,这些操作都可以在前端通过点击按钮来完成,并且伴随着简单的动态效果,轻松实现表格数据排序. HTML 页面上是一个简单的数据表格,我们在数据行中分别放置"上移","下移"和"置顶"三个链接,并且分别定义三个class属性

TP-Link面板式AP与吸顶式AP是利用网线的哪几根线芯进行供电

  tp-link面板式AP(TL-AP300I-PoE)和吸顶式AP(TL-AP300C-PoE.TL-AP450C-PoE)支持IEEE 802.3af/at,是标准的PoE受电设备,同时支持PoE Mode A(电力传输和数据传输共用双绞线对)和 PoE Mode B(电力传输和数据传输采用单独的双绞线对)两种供电模式. PoE Mode A电力传输和数据传输共用1.2.3.6线对;PoE Mode B电力传输使用4.5.7.8线对,数据传输使用1.2.3.6线对. 电力传输和数据传输采用

jQuery实现表格行上下移动和置顶效果_jquery

我们在操作列表数据的时候,需要将数据行排列顺序进行调整,如上移和下移行,将行数据置顶等,这些操作都可以在前端通过点击按钮来完成,并且伴随着简单的动态效果,轻松实现表格数据排序. HTML 页面上是一个简单的数据表格,我们在数据行中分别放置"上移","下移"和"置顶"三个链接,并且分别定义三个class属性,我们来通过jQuery实现这些操作. <table class="table"> <tr> <

图片-安卓ExpandListView 实现显示不同的布局效果

问题描述 安卓ExpandListView 实现显示不同的布局效果