安卓當(dāng)下最流行的吸頂效果的實(shí)現(xiàn)(下)
作者:佚名 
  今天接著上次讓我使用ItemDecoration來(lái)完成可推動(dòng)的懸浮導(dǎo)航欄的效果。
 接上文
***步:首先我們來(lái)寫(xiě)一個(gè)類(lèi),它起標(biāo)記的作用,來(lái)放每一個(gè)item的對(duì)應(yīng)的懸浮欄的字符串
- public class NameBean {
 - String name;
 - public String getName() {
 - return name;
 - }
 - public void setName(String name) {
 - this.name = name;
 - }
 - }
 
第二步:自定義一個(gè)SectionDecoration 類(lèi) 繼承 RecyclerView的ItemDecoration
- public class SectionDecoration extends RecyclerView.ItemDecoration {
 - private static final String TAG = "SectionDecoration";
 - private List<NameBean> dataList;
 - private DecorationCallback callback;
 - private TextPaint textPaint;
 - private Paint paint;
 - private int topGap;
 - private int alignBottom;
 - private Paint.FontMetrics fontMetrics;
 - public SectionDecoration(List<NameBean> dataList, Context context, DecorationCallback decorationCallback) {
 - Resources res = context.getResources();
 - this.dataList = dataList;
 - this.callback = decorationCallback;
 - //設(shè)置懸浮欄的畫(huà)筆---paint
 - paint = new Paint();
 - paint.setColor(res.getColor(R.color.colorGray));
 - //設(shè)置懸浮欄中文本的畫(huà)筆
 - textPaint = new TextPaint();
 - textPaint.setAntiAlias(true);
 - textPaint.setTextSize(DensityUtil.dip2px(context, 14));
 - textPaint.setColor(Color.DKGRAY);
 - textPaint.setTextAlign(Paint.Align.LEFT);
 - fontMetrics = new Paint.FontMetrics();
 - //決定懸浮欄的高度等
 - topGap = res.getDimensionPixelSize(R.dimen.sectioned_top);
 - //決定文本的顯示位置等
 - alignBottom = res.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);
 - Log.i(TAG, "getItemOffsets:" + pos);
 - String groupId = callback.getGroupId(pos);
 - if (groupId.equals("-1")) return;
 - //只有是同一組的***個(gè)才顯示懸浮欄
 - if (pos == 0 || isFirstInGroup(pos)) {
 - outRect.top = topGap;
 - if (dataList.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();
 - float lineHeight = textPaint.getTextSize() + fontMetrics.descent;
 - 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());
 - //下一個(gè)和當(dāng)前不一樣移動(dòng)當(dāng)前
 - if (position + 1 < itemCount) {
 - String nextGroupId = callback.getGroupId(position + 1);
 - //組內(nèi)***一個(gè)view進(jìn)入了header
 - if (nextGroupId != groupId && viewBottom < textY) {
 - 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);
 - }
 - }
 - /**
 - * 判斷是不是組中的***個(gè)位置
 - *
 - * @param pos
 - * @return
 - */
 - private boolean isFirstInGroup(int pos) {
 - if (pos == 0) {
 - return true;
 - } else {
 - // 因?yàn)槭歉鶕?jù) 字符串內(nèi)容的相同與否 來(lái)判斷是不是同意組的,所以此處的標(biāo)記id 要是String類(lèi)型
 - // 如果你只是做聯(lián)系人列表,懸浮框里顯示的只是一個(gè)字母,則標(biāo)記id直接用 int 類(lèi)型就行了
 - String prevGroupId = callback.getGroupId(pos - 1);
 - String groupId = callback.getGroupId(pos);
 - //判斷前一個(gè)字符串 與 當(dāng)前字符串 是否相同
 - if (prevGroupId.equals(groupId)) {
 - return false;
 - } else {
 - return true;
 - }
 - }
 - }
 - //定義一個(gè)借口方便外界的調(diào)用
 - interface DecorationCallback {
 - String getGroupId(int position);
 - String getGroupFirstLine(int position);
 - }
 - }
 
第三步:在向list集合中先把每一個(gè)item的 起“標(biāo)記”作用的字符串都加進(jìn)去
- setPullAction(comingslist);
 
- private void setPullAction(List<WaitMVBean.DataBean.ComingBean> comingslist) {
 - dataList = new ArrayList<>();
 - for (int i = 0; i < comingslist.size(); i++) {
 - NameBean nameBean = new NameBean();
 - String name0 = comingslist.get(i).getComingTitle();
 - nameBean.setName(name0);
 - dataList.add(nameBean);
 - }
 - }
 
第四步:在setAdapter() 前,為RecyclerView添加ItemDecoration:
- recyclerView.addItemDecoration(new SectionDecoration(dataList,mContext, new SectionDecoration.DecorationCallback() {
 - //返回標(biāo)記id (即每一項(xiàng)對(duì)應(yīng)的標(biāo)志性的字符串)
 - @Override
 - public String getGroupId(int position) {
 - if(dataList.get(position).getName()!=null) {
 - return dataList.get(position).getName();
 - }
 - return "-1";
 - }
 - //獲取同組中的***個(gè)內(nèi)容
 - @Override
 - public String getGroupFirstLine(int position) {
 - if(dataList.get(position).getName()!=null) {
 - return dataList.get(position).getName();
 - }
 - return "";
 - }
 - }));
 
這樣就完成了~
再看一眼最終效果感受一下:
責(zé)任編輯:龐桂玉 
                    來(lái)源:
                    安卓開(kāi)發(fā)精選
 
















 
 
 









 
 
 
 