前言
又是新的一周,虽然今天上海的天气不咋样,但是温度相比上周明显有一点上升,总不至于出门上班路上被冻成狗了。上周六晚去看了《寻龙诀》,只怪小伙伴决定太迟,最后只能看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的使用全部更新完吧,谢谢体谅。还有如果对我的文章有什么建议的,可以在后面给我回复留言,我一定会一一回复的,当然自己本身就不咋样,写的东西也不深,希望大家海涵。