Android RecyclerView 梦幻般的控件 使用解析(二)

前言

又是新的一周,虽然今天上海的天气不咋样,但是温度相比上周明显有一点上升,总不至于出门上班路上被冻成狗了。上周六晚去看了《寻龙诀》,只怪小伙伴决定太迟,最后只能看10点半场次的,看完都0点40了,回家路上还下雨,真是一次不如意的观影。不过影片本身来说还是不错的,完虐之前的《九层妖塔》。好了,废话少说进入正题。。。


简介

上周五我们讲到了RecyclerView的最基本的使用以及一些概念,详情请看Android RecyclerView 梦幻般的控件 使用解析(一)
今天我们就来讲讲如何添加分隔线,以及怎么自定义分隔线。


使用方法

其实很简单,就是通过addItemDecoration(RecyclerView.ItemDecoration)添加分隔线。

那么具体怎么用,我们一步一步来看一下哈;

首先我们先看一下该方法中的参数为RecyclerView.ItemDecoration,是一个抽象类,源码如下(删除了所有的注释):

public static abstract class ItemDecoration {

        public void onDraw(Canvas c, RecyclerView parent, State state) {
            onDraw(c, parent);
        }
        @Deprecated
        public void onDraw(Canvas c, RecyclerView parent) {
        }
        public void onDrawOver(Canvas c, RecyclerView parent, State state) {
            onDrawOver(c, parent);
        }
        @Deprecated
        public void onDrawOver(Canvas c, RecyclerView parent) {
        }
        @Deprecated
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            outRect.set(0, 0, 0, 0);
        }
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
            getItemOffsets(outRect,((LayoutParams)
            view.getLayoutParams()).getViewLayoutPosition(),
                    parent);
        }
    }

我们可以看到其实里面就3对方法,分别是onDraw();onFrawOver()还有一个是getItemOffsets(),最后一个方法不难猜出就是设置了decoration的偏移量什么的,所以我要要去继承该类,并重写其中的方法即可,这里我就不带大家写了,因为有现成的轮子供大家使用:DividerItemDecoration(感谢大神们的无私奉献)

package com.mic.blin.myrecyclerview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class DividerItemDecoration extends RecyclerView.ItemDecoration {

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

    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;

    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;

    private Drawable mDivider;

    private int mOrientation;

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

    public void setOrientation(int orientation) {
        if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
            throw new IllegalArgumentException("invalid orientation");
        }
        mOrientation = orientation;
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent) {
        if (mOrientation == VERTICAL_LIST) {
            drawVertical(c, parent);
        } else {
            drawHorizontal(c, parent);
        }
    }

    public void drawVertical(Canvas c, RecyclerView parent) {
        final int left = parent.getPaddingLeft();
        final int right = parent.getWidth() - parent.getPaddingRight();

        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.getBottom() + params.bottomMargin;
            final int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    public void drawHorizontal(Canvas c, RecyclerView parent) {
        final int top = parent.getPaddingTop();
        final int bottom = parent.getHeight() - parent.getPaddingBottom();

        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 left = child.getRight() + params.rightMargin;
            final int right = left + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }

    @Override
    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
        if (mOrientation == VERTICAL_LIST) {
            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
        } else {
            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
        }
    }
}

实战

该类已经很完美的实现了RecyclerView.ItemDecoration(Manager为LinearLayoutManager时),可以看到该类是获取系统的android.R.attr.listDivider来作为分隔线的,好了我们就在之前的代码上添加一行代码:


//添加分隔线
        recyhclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));

然后运行,效果如下:
这里写图片描述

当然该分割线是默认的属性,而我们又用了系统的listDivider,这样很方便我们去随意的改变,如下:

<!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
      <item name="android:listDivider">@drawable/itemdecoration_bg</item>  
    </style>

然后你可以自己去写一个itemdecoration_bg.xml就好了,大胆的发挥你的所能。


总结

其实官方是没有给我们提供分隔线,也不知道是处于什么原因,总是大神有的是,有很多东西我们都可以借鉴过来,嘿嘿。使用方法我也就不再强调了,就是很简单的一行代码,大家有兴趣的话可以自己去写一下RecyclerView.ItemDecoration这个类的继承,然后看看能不能有其他的方法。
好了我就不带大家写了,因为临时有事儿,今天就先写到这里吧到时候再给大家补上一点自定义分隔线的东西,请勿喷。。。


PS

由于公司项目需要,有个大工程我要去弄一下,可能会有点忙,尽量在元旦之前把RecyclerView的使用全部更新完吧,谢谢体谅。还有如果对我的文章有什么建议的,可以在后面给我回复留言,我一定会一一回复的,当然自己本身就不咋样,写的东西也不深,希望大家海涵。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值