RecyclerView 快速添加分割线

android

很多使用RecyclerView 的同学肯定有件很蛋疼的事情,RecyclerVeiw 没有分割线。
大多数的时候我们都是选择直接在ItemViewHolder 布局的底部自己添加一个分割线View,
这种方法简单暴力,效果明显。但并不想影响我们尝试其他的方法来实现。

其实Google在RecyclerView 中内置了很多内部类,其中有一个名为ItemDecoration的类,字面翻译为 “选项装饰”。
我们先看看android api 给他的定

itemDecoration允许在指定的itemView 添加一个绘画 和 布局偏移量, 它可以被用于绘制分割线,亮点,可视化的分组边界 等。

在这个类的介绍中我们看到了可以用这个类来制作分割线,ok, 下面我们来看看如何用它来制作一个简单的分割线吧。

编写自己的RecyclerView

Activity_mian.layout:

?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="eebochina.com.testtechniques.MainActivity"
    >
    <android.support.v7.widget.RecyclerView
        android:id="@+id/test_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/darker_gray"
        >
    </android.support.v7.widget.RecyclerView>
</RelativeLayout>

在这个布局中, 我给RecyclerView设置了深灰色的背景,为什么要设置, 后面会具体说明。

MainActivity.java:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRecyclerView = (RecyclerView) findViewById(R.id.test_recyclerview);

        LinearLayoutManager manager = new LinearLayoutManager(this);
        manager.setOrientation(LinearLayoutManager.VERTICAL);
        mRecyclerView.setLayoutManager(manager);

        mRecyclerView.setAdapter(new MyAdapter());
    }

    class MyAdapter extends RecyclerView.Adapter {
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return new MyViewHolder(LayoutInflater.from(MainActivity.this).inflate(R.layout.item_layout, parent, false));
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

        }

        @Override
        public int getItemCount() {
            return 15;
        }
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        public MyViewHolder(View itemView) {
            super(itemView);
        }
    }
}

Item_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="just a test"
        android:background="@android:color/white"
        android:padding="10dp"
        />
</LinearLayout>

简单的设置了RecyclerView 的adapter 并且为它添加了 15项数据。
为每个item设置为背景为白色, 我们运行下看看效果。

现在并没有分割线, ok 下面我们来编写 ItemDecoration类。

MyItemDecoration.java:

class MyItemDecoration extends RecyclerView.ItemDecoration {
    /**
     *
     * @param outRect 边界
     * @param view recyclerView ItemView
     * @param parent recyclerView
     * @param state recycler 内部数据管理
     */
    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        //设定底部边距为1px
        outRect.set(0, 0, 0, 1);
    }
}

编写完成我们将这个类添加进RecyclerView。

.........
mRecyclerView.setLayoutManager(manager);
//添加装饰类
mRecyclerView.addItemDecoration(new MyItemDecoration());
mRecyclerView.setAdapter(new MyAdapter());
.........

我们在setAdapter 前面添加 我们自定义的itemDecoration();
Ok 我们再运行一次 看下有什么效果。

OK,分割线出现了,下面我们来看看到底是如何实现的吧。

先看下 androidApi 对 ItemDecoration 中的 getItemOffsts 方法的介绍

在上面的介绍中我们主要看下面这段话:


大意是检索给定Item的所有偏移量,outRect每个属性都指定item应插入的像素数,简单的padding 或者 margin, 默认实现是设置outRect的边界为零。

从介绍来看,这个是为每个itemView设置边界值得方法。
在我们自定义的代码中, 我们设置了底部边距为1像素,我们的RecyclerView的背景为灰色。 所以我们就可以看到了灰色的分割线。

这种实现方式有一种取巧的感觉。
而且因为Rect不能设置颜色,而且参数只能为整形。就限制了很多使用场景。

还不满足?那只有看下这个博客了:
http://www.jianshu.com/p/4eff036360da

感谢大家的阅读。如有什么更好的意见,欢迎指出。一起学习。
Ps:本人英文有限,翻译很不准。

推荐阅读更多精彩内容