RecyclerView的使用(2)

RecyclerView設(shè)置分割線

RecyclerView的分割線去設(shè)置布局器净?太low了!
RecyclerView提供了一個(gè)類設(shè)置分割線鹤树,我們需繼承 RecyclerView.ItemDecoration
然后繪制分割線。
代碼如下:

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

    /**
     * RecyclerView布局方向,設(shè)置默認(rèn)的
     */
    private int mOrientation = LinearLayoutManager.VERTICAL;

    /**
     * 分割線寬度
     */
    private int mItemSize = 1;

    /**
     * 畫筆
     */
    private Paint mPaint;

    private Drawable mDivider;

    private static final int[] ATTRS = new int[]{
            android.R.attr.listDivider
    };

    public DividerItemDecoration(Context context, int orientation) {
        this.mOrientation = orientation;
        if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
            throw new IllegalArgumentException("請(qǐng)傳入正確參數(shù)");
        }
        mItemSize = (int) TypedValue.applyDimension(mItemSize, TypedValue.COMPLEX_UNIT_DIP, context.getResources().getDisplayMetrics());
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLUE);
         /*設(shè)置填充*/
        mPaint.setStyle(Paint.Style.FILL);
    }


    public DividerItemDecoration(Context context, int orientation,String na) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }


    /**
     * 繪制縱向 item 分割線
     *
     * @param canvas
     * @param parent
     */
    private void drawVertical(Canvas canvas, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int top = child.getBottom() + layoutParams.bottomMargin;
            final int bottom = top + mItemSize;
            if (mPaint==null){
                canvas.drawRect(left, top, right, bottom, mPaint);
            }else {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
        }
    }

    /**
     * 繪制橫向 item 分割線
     *
     * @param canvas
     * @param parent
     */
    private void drawHorizontal(Canvas canvas, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
        final int childSize = parent.getChildCount();
        for (int i = 0; i < childSize; i++) {
            final View child = parent.getChildAt(i);
            RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
            final int left = child.getRight() + layoutParams.rightMargin;
            final int right = left + mItemSize;
            if (mPaint==null){
                canvas.drawRect(left, top, right, bottom, mPaint);
            }else {
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(canvas);
            }
        }
    }

    //設(shè)置偏移量
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if (mOrientation == LinearLayoutManager.VERTICAL) {
            outRect.set(0, 0, 0, mItemSize);
        } else {
            outRect.set(0, 0, mItemSize, 0);
        }
    }
}

首先獲取到布局的方向至扰,根據(jù)方向繪制間隔 也就是在onDraw方法中。先判斷后執(zhí)行资锰。
繪制間隔線有兩種方法一種是畫筆直接畫敢课,一種是自定義Drawable繪制。這里給了兩個(gè)構(gòu)造方法绷杜,兩個(gè)參數(shù)的是畫筆
三個(gè)參數(shù)的是Drawable直秆,第三個(gè)參數(shù)直接傳null就行了。

最后要設(shè)置偏移量鞭盟,在getItemOffsets中圾结。

上面只是線性布局的分割線的設(shè)置,網(wǎng)格布局的分割線怎么設(shè)置呢齿诉?
網(wǎng)格布局的分割線則比較麻煩筝野,直接上代碼

public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {

    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};
    private Drawable mDivider;

    public DividerGridItemDecoration(Context context) {
        final TypedArray a = context.obtainStyledAttributes(ATTRS);
        mDivider = a.getDrawable(0);
        a.recycle();
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {

        drawHorizontal(c, parent);
        drawVertical(c, parent);

    }

    private int getSpanCount(RecyclerView parent) {
        // 列數(shù)
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {

            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager).getSpanCount();
        }
        return spanCount;
    }
    /**
     * 繪制縱向分割線
     *
     */
    public void drawHorizontal(Canvas c, RecyclerView parent) {
        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);
            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int left = child.getLeft() - params.leftMargin;
            final int right = child.getRight() + params.rightMargin
                    + mDivider.getIntrinsicWidth();
            final int top = child.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            final View child = parent.getChildAt(i);

            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
                    .getLayoutParams();
            final int top = child.getTop() - params.topMargin;
            final int bottom = child.getBottom() + params.bottomMargin;
            final int left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicWidth();

            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    private boolean isLastColum(RecyclerView parent, int pos, int spanCount,
                                int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            if ((pos + 1) % spanCount == 0) {// 如果是最后一列,則不需要繪制右邊
                return true;
            }
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                if ((pos + 1) % spanCount == 0) {// 如果是最后一列粤剧,則不需要繪制右邊
                    return true;
                }
            } else {
                childCount = childCount - childCount % spanCount;
                if (pos >= childCount)// 如果是最后一列歇竟,則不需要繪制右邊
                    return true;
            }
        }
        return false;
    }

    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount, int childCount) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            childCount = childCount - childCount % spanCount;
            if (pos >= childCount)// 如果是最后一行,則不需要繪制底部
                return true;
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            int orientation = ((StaggeredGridLayoutManager) layoutManager)
                    .getOrientation();
            // StaggeredGridLayoutManager 且縱向滾動(dòng)
            if (orientation == StaggeredGridLayoutManager.VERTICAL) {
                childCount = childCount - childCount % spanCount;
                // 如果是最后一行抵恋,則不需要繪制底部
                if (pos >= childCount)
                    return true;
            } else {   // StaggeredGridLayoutManager 且橫向滾動(dòng)
                // 如果是最后一行途蒋,則不需要繪制底部
                if ((pos + 1) % spanCount == 0) {
                    return true;
                }
            }
        }
        return false;
    }


    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        int spanCount = getSpanCount(parent);
        int childCount = parent.getAdapter().getItemCount();
        if (isLastRaw(parent, itemPosition, spanCount, childCount)) {// 如果是最后一列,則不需要顯示右邊分割線
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        } else if (isLastColum(parent, itemPosition, spanCount, childCount)) {// 如果是最后一行馋记,則不需要顯示底部分割線
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(),
                    mDivider.getIntrinsicHeight());
        }
    }
}

在onDraw中有連個(gè)方法:drawHorizontal 與drawVertical分別是繪制縱向分割線 繪制橫向分割線
最后設(shè)置偏移量getItemOffsets這里就要做判斷是否顯示分割線
isLastRaw判斷如果是最后一列号坡,則不需要顯示右邊分割線
isLastColum如果是最后一行,則不需要顯示底部分割線

使用:

   recyclerView.addItemDecoration(new DividerGridItemDecoration(this));
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末梯醒,一起剝皮案震驚了整個(gè)濱河市宽堆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茸习,老刑警劉巖畜隶,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡籽慢,警方通過(guò)查閱死者的電腦和手機(jī)浸遗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)箱亿,“玉大人跛锌,你說(shuō)我怎么就攤上這事〗焱铮” “怎么了髓帽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)脑豹。 經(jīng)常有香客問(wèn)我郑藏,道長(zhǎng),這世上最難降的妖魔是什么瘩欺? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任必盖,我火速辦了婚禮,結(jié)果婚禮上俱饿,老公的妹妹穿的比我還像新娘歌粥。我一直安慰自己,他們只是感情好稍途,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著砚婆,像睡著了一般械拍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上装盯,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天坷虑,我揣著相機(jī)與錄音,去河邊找鬼埂奈。 笑死迄损,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的账磺。 我是一名探鬼主播芹敌,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼垮抗!你這毒婦竟也來(lái)了氏捞?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤冒版,失蹤者是張志新(化名)和其女友劉穎液茎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捆等,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年滞造,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栋烤。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡秘通,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出崭添,到底是詐尸還是另有隱情揣非,我是刑警寧澤,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布达址,位于F島的核電站蔑祟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏沉唠。R本人自食惡果不足惜疆虚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望满葛。 院中可真熱鬧径簿,春花似錦、人聲如沸嘀韧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锄贷。三九已至译蒂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谊却,已是汗流浹背柔昼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炎辨,地道東北人捕透。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像碴萧,于是被迫代替她去往敵國(guó)和親乙嘀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,302評(píng)論 25 707
  • 特別聲明: 本文轉(zhuǎn)發(fā)自:【江清清的博客】http://blog.csdn.net/developer_jiangq...
    _猜火車_閱讀 37,461評(píng)論 11 70
  • 今年第21號(hào)“莎莉嘉”臺(tái)風(fēng)和第22號(hào)臺(tái)風(fēng)“海馬”正襲擊我國(guó)華南沿海地區(qū)嘉冒,因此我所在的城市也不例外曹货。 昨天本來(lái)是學(xué)生...
    柳書(shū)閱讀 1,070評(píng)論 0 0
  • 你現(xiàn)在的男朋友很愛(ài)你银觅,但你的前男友過(guò)來(lái)找你了礼饱,你會(huì)怎么選? 電視里究驴,熊青春選擇了她的前男友镊绪。你會(huì)選誰(shuí)? 花了一下午...
    少年的樣子閱讀 586評(píng)論 3 4
  • 悵臥新春白袷衣洒忧,白門寥落意多違蝴韭。 紅樓隔雨相望冷,珠箔飄燈獨(dú)自歸熙侍。 遠(yuǎn)路應(yīng)悲春晼晚榄鉴,殘宵猶得夢(mèng)依稀。 玉珰緘札何由...
    aeac13066d77閱讀 146評(píng)論 0 0