Recycleview模仿瑞幸咖啡菜單物品列表

  • 首先得明白一點(diǎn)Recycleview的ItemDecoration非常強(qiáng)大,你可以使用它實(shí)現(xiàn)listview的分割線,懸浮窗,甚至一些非常炫的動(dòng)畫。
  • 先看下效果圖
    Recycleview模仿瑞幸咖啡菜單物品列表

ItemDecoration

  • onDraw():和普通view的onDraw差不多,就是繪制在畫布上繪制東西。
  • onDrawOver():就是基于onDraw上再次繪制點(diǎn)東西,over的意思。
  • getItemOffsets():Recycleview可以通過他拿到每一個(gè)item的間距,所以只需要控制這個(gè)間距,并在間距里利用onDrawOver再繪制你想繪制的東西。

    實(shí)現(xiàn)這個(gè)的思路,我們只需要在指定的的行數(shù)通過getItemOffsets預(yù)留出我們要空出的高度,然后通過onDrawOver繪制出你所希望的view即可。

    為南安等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及南安網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、南安網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!


一:手動(dòng)構(gòu)造數(shù)據(jù)格式,如下,返回list

Goods goods1 = new Goods("人氣TOP", "正果拿鐵1", "Y27", "默認(rèn):大/單糖/熱");
Goods goods99 = new Goods("人氣TOP", "正果拿鐵2", "Y27", "默認(rèn):大/單糖/熱");
Goods goods91 = new Goods("人氣TOP", "正果拿鐵3", "Y27", "默認(rèn):大/單糖/熱");
Goods goods2 = new Goods("大師咖啡", "拿鐵", "Y27", "默認(rèn):大/單糖/熱");
Goods goods3 = new Goods("大師咖啡", "香草拿鐵", "Y24", "默認(rèn):大/單糖/熱");
Goods goods4 = new Goods("大師咖啡", "焦糖拿鐵", "Y26", "默認(rèn):大/半糖/熱");
List<Goods> list = new ArrayList<>();

二:書寫自己的ItemDecoration

  • getItemOffsets預(yù)留空間,只需要在每個(gè)數(shù)組的第一個(gè)數(shù)據(jù)預(yù)留一個(gè)高度,比如第一個(gè)人氣TOP,第一個(gè)大師咖啡。
第一個(gè)必須預(yù)留,當(dāng)前位置的name和前一個(gè)不相等則為預(yù)留空間
  @Override
public boolean isParent(int position) {
    if (position == 0) return true;
        if (!list.get(position).getType().equals(list.get(position - 1).getType()))
            return true;
    return false;
}
//是否為當(dāng)前最后一個(gè)item
protected boolean lastOneInGroup(int position) {
        String parentName = mDecorListener.parentName(position);
        String nextGroupName;
        try {
            nextGroupName = mDecorListener.parentName(position + 1);
        } catch (Exception e) {
            nextGroupName = null;
        }
        if (nextGroupName == null) {
            return false;
        }
        return !TextUtils.equals(parentName, nextGroupName);//與下一行的name不一樣說明當(dāng)前是最后一行
    }

由上isParent判斷是第一個(gè)的返回你要預(yù)留的高度大小,否則為不需要空間0
 @Override
  public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        int position = parent.getChildAdapterPosition(view);
        if (parent.getLayoutManager() instanceof LinearLayoutManager && mDecorListener.isParent(position)) {
            outRect.top = decorationHeight;
            return;
        }
        outRect.top = 0;
    }
  • 在預(yù)留的空間上畫上你的view
 @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDrawOver(c, parent, state);
        final int itemCount = state.getItemCount(); 全部item的數(shù)量
        final int childCount = parent.getChildCount(); 可看見的排除懸停的分割線的個(gè)數(shù)
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();
        for (int i = 0; i < childCount; i++) {
            View childView = parent.getChildAt(i);
            int position = parent.getChildAdapterPosition(childView);//就是當(dāng)前可見每一行的position,從0開始
            //默認(rèn)第一個(gè)就是有個(gè)Group
            if (mDecorListener.isParent(position) || i == 0) {//中第一個(gè)位置和可見的第一個(gè)才有這個(gè)懸停
                //繪制懸浮,
                int bottom = Math.max(decorationHeight, (childView.getTop() + parent.getPaddingTop()));
                //決定當(dāng)前頂部第一個(gè)懸浮Group的bottom,拿到item高度和規(guī)定高度對(duì)比,只是選擇一個(gè)合適的高度定義分割線
                if (position + 1 < itemCount) {
                    //下一組的第一個(gè)View接近頭部
                    int viewBottom = childView.getBottom();
                    if (lastOneInGroup(position) && viewBottom < bottom) {
                        bottom = viewBottom;                    //如果這個(gè)關(guān)掉,會(huì)覆蓋,頂上去效果失去,其實(shí)viewBottom逐漸變?yōu)?,這樣動(dòng)態(tài)的放置即將消失的懸浮攔,看上去就是下一個(gè)懸浮攔頂上來的
                    }
                }
                drawDecoration(c, position, left, right, bottom, parent);
                stickyHeaderPosArray.put(position, bottom);
            } 
        }
    }

    private void drawDecoration(Canvas c, int position, int left, int right, int bottom, RecyclerView parent) {
        c.drawRect(left, bottom - decorationHeight, right, bottom, mGroutPaint);
        Paint.FontMetrics fm = mTextPaint.getFontMetrics();
        //文字豎直居中顯示
        float baseLine = bottom - (decorationHeight - (fm.bottom - fm.top)) / 2 - fm.bottom;
        //獲取文字寬度
        mSideMargin = Math.abs(mSideMargin);
        c.drawText(mDecorListener.parentName(position), left + mSideMargin, baseLine, mTextPaint);//x軸,baseLine
        Rect rect = new Rect();//為了得到當(dāng)前text的屬性
        mTextPaint.getTextBounds(mDecorListener.parentName(position), 0, mDecorListener.parentName(position).length(), rect);
        //繪制那條橫線
        c.drawLine(left + mSideMargin * 2 + rect.width(), baseLine - rect.height() / 2, parent.getWidth() -
                mSideMargin, baseLine - rect.height() / 2, mTextPaint);

    }

完結(jié)

分享標(biāo)題:Recycleview模仿瑞幸咖啡菜單物品列表
網(wǎng)站URL:http://muchs.cn/article44/pideee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、全網(wǎng)營(yíng)銷推廣自適應(yīng)網(wǎng)站、移動(dòng)網(wǎng)站建設(shè)動(dòng)態(tài)網(wǎng)站、虛擬主機(jī)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)