RecyclerView 设置水平Item间距

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RecyclerView 设置水平Item间距相关的知识,希望对你有一定的参考价值。

参考技术A 每个Item之间需要设置间距,但是第一个和最后一个Item到RecyclerView边缘的距离要为0不能有距离。

思路1、首先在item.xml里面设置marginLeft与marginRight,然后在onBindViewHolder里面获取到第一个View,动态的去修改marginLeft为0同理marginRight
思路2、recyclerView.addItemDecoration

我只展示思路2的方式,调用步骤如下

RecyclerView—— ItemDecoration

Recycler没有直接提供设置item间距的功能,而是提供了一个更强大的基类ItemDecoration。类如其名,这个类是Item的装饰。它既可以作为Item的间距,也可以在item之间绘制分隔线,甚至可以对每个item的边缘都进行不同的绘制。

ItemDecoration本身是一个虚类,我们在使用时,只能继承它。

  先看一个简单版本,这个版本的ItemDecoration只提供一个Item的间距。

import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;

/**
 * Created by fishboneLsy on 2016/6/25.
 */
public class DivideDecoration extends RecyclerView.ItemDecoration{

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        if (parent.getChildAdapterPosition(view) < parent.getAdapter().getItemCount() - 1){
            outRect.bottom = 30;
        }
    }
}

  上面的例子中,我们将每个item下面,留出30像素的间隔,并且增加一个判断语句,即最后一个item的下方不会加间隔。从上面的例子举一反三,我们可以为不同的item,加上不同的空格。

 

----------------------------------------------------------------------------------------------------------------------

  除了设置间隔外,我们还可以绘制分隔线:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by fishboneLsy on 2016/6/25.
 */
public class DrawerDecoration extends RecyclerView.ItemDecoration {


    Drawable mDivider;

    public DrawerDecoration(Context context){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher ,null);
        }else {
            mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher );
        }
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        int left = parent.getPaddingLeft();
        int right = parent.getWidth() - parent.getPaddingRight();

        int childCount = parent.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);

            RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

            int top = child.getBottom() + params.bottomMargin;
            int bottom = top + mDivider.getIntrinsicHeight();

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

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        outRect.bottom = mDivider.getIntrinsicHeight();
    }
}

  由上面的例子,我们可以看到,分隔线的绘制实质是在一个循环中完成的。也就是说,我们可以为每个item绘制不同的分隔线。我们可以自己在Canvas上绘制,也可以直接将一个Drawable绘制在Canvas上,上面的代码,就是将一个Drawable直接绘制在Canvas上。

  在这个例子中,我们的outRect.bottom就必须获取Drawable的实质高度了。这样的一个类,为我们提供了极大的分隔线订制的灵活性。 也许打造了一个体验良好的列表控件,提供了很多方便。

 

Done~

importandroid.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
* Created by fishboneLsy on 2016/6/25.
*/
public class DrawerDecoration extends RecyclerView.ItemDecoration {


Drawable mDivider;

public DrawerDecoration(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher ,null);
}else {
mDivider = context.getResources().getDrawable(R.mipmap.ic_launcher );
}
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
int left = parent.getPaddingLeft();
int right = parent.getWidth() - parent.getPaddingRight();

int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
View child = parent.getChildAt(i);

RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

int top = child.getBottom() + params.bottomMargin;
int bottom = top + mDivider.getIntrinsicHeight();

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

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
outRect.bottom = mDivider.getIntrinsicHeight();
}
}

以上是关于RecyclerView 设置水平Item间距的主要内容,如果未能解决你的问题,请参考以下文章

RecyclerView 上下左右四种间距的设置方法

关于recyclerview 设置item之间的距离

Android View 上下左右四种间距的设置方法

RecyclerView—— ItemDecoration

RecyclerView 的item显示的间距过大(item占满父布局)

java 自动为RecyclerView项添加相等的间距。可以处理水平,垂直和网格显示模式