【问题标题】:Add margins to divider in RecyclerView在 RecyclerView 中为分隔线添加边距
【发布时间】:2017-05-23 15:40:21
【问题描述】:

我正在构建一个使用RecyclerView 的android 应用程序。我想在RecyclerView 中添加分隔符,我使用以下代码:

DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.addItemDecoration(dividerItemDecoration);

到目前为止一切正常。但是,分隔线采用全屏大小,我想为其添加边距。有什么方法可以为分隔线添加边距,方法是为绘制的矩形添加一些空间,而不是通过创建带有边距的自定义可绘制形状并将其添加到RecyclerView

【问题讨论】:

标签: android android-recyclerview divider


【解决方案1】:

我认为最直接的解决方案是在装饰对象上使用 setDrawable 方法并将其传递给带有您想要的边距的 inset 值的 inset drawable。像这样:

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

TypedArray a = context.obtainStyledAttributes(ATTRS);
Drawable divider = a.getDrawable(0);
int inset = getResources().getDimensionPixelSize(R.dimen.your_margin_value);
InsetDrawable insetDivider = new InsetDrawable(divider, inset, 0, inset, 0);
a.recycle();

DividerItemDecoration itemDecoration = new DividerItemDecoration(context, DividerItemDecoration.VERTICAL);
itemDecoration.setDrawable(insetDivider);
recyclerView.addItemDecoration(itemDecoration);

【讨论】:

  • 天才!非常感谢!
  • 简单正确的答案。如果可以重用和修改现有的 ItemDecoration,请不要实现自己的 ItemDecoration。
  • 我在调用obtainStyledAttributes 时遇到 OOM。我正在使用 kotlin
  • 如何设置此分隔线的高度,使其更厚?
  • @On_my_way_to_Dev_Life 您可能必须修改源可绘制对象以使其更厚。
【解决方案2】:

shape.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#E6E7F0" />
    <size android:height="1dp" />
</shape>

layer.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/shape"
        android:left="16dp"
        android:right="16dp" />

</layer-list>

代码

val itemDecoration = DividerItemDecoration(context, DividerItemDecoration.VERTICAL)
itemDecoration.setDrawable(resources.getDrawable(R.drawable.layer, null))
recyclerView.addItemDecoration(itemDecoration)

【讨论】:

【解决方案3】:

使用它并根据您的要求进行自定义。

public class DividerItemDecoration extends RecyclerView.ItemDecoration {

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

    private Drawable divider;

    /**
     * Default divider will be used
     */
    public DividerItemDecoration(Context context) {
        final TypedArray styledAttributes = context.obtainStyledAttributes(ATTRS);
        divider = styledAttributes.getDrawable(0);
        styledAttributes.recycle();
    }

    /**
     * Custom divider will be used
     */
    public DividerItemDecoration(Context context, int resId) {
        divider = ContextCompat.getDrawable(context, resId);
    }

    @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 + divider.getIntrinsicHeight();

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

【讨论】:

  • 在我的情况下,它只在最后一项之后显示一次。
【解决方案4】:

您可以为回收站视图创建自己的物品装饰。 这是相同的代码。

public class SimpleItemDecorator extends RecyclerView.ItemDecoration {

    int space;
    boolean isHorizontalLayout;
    public SimpleItemDecorator(int space) {
        this.space = space;
    }

    public SimpleItemDecorator(int space, boolean isHorizontalLayout) {
        this.space = space;
        this.isHorizontalLayout = isHorizontalLayout;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        if(isHorizontalLayout)
        {
            outRect.bottom=space;
            outRect.right=space;
            outRect.left=space;
            outRect.top=space;

        } else {
            outRect.bottom = space;
            if (parent.getChildAdapterPosition(view) == 0)
                outRect.top = space;
            else
                outRect.top = 0;

        }


    }
}

要将它与您的 recyclerview 一起使用,您可以这样做:

 recyclerView.addItemDecoration(new SimpleItemDecorator(5));

【讨论】:

  • 好的...它会如何绘制任何东西?该 sn-p 中没有分隔符
  • @Sever 它在增加空间而不是绘制任何东西。
【解决方案5】:

详细说明@SeptimusX75:如果您(像我一样)更喜欢在 XML 中做 UI 工作,您可以创建一个嵌入的可绘制文件。您必须创建第二个 XML 文件,但作为回报,您的代码会变得更清晰,我说这是值得的 :-)。

[UPDATE] 用户@Zhou Hongbo 在 cmets 中建议,只使用一个 XML 文件:divider.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/divider_base"
    android:insetRight="20dp"
    android:insetLeft="20dp">

    <shape>
        <android:shape="rectangle">
        <size android:height="1dp" />
        <solid android:color="@color/dividerColor" />
    </shape>

</inset>

[旧答案]:

divider_base.xml (实际的分隔符)

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:height="1dp" />
    <solid android:color="@color/dividerColor" />
</shape>

divider.xml (插图)

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/divider_base"
    android:insetRight="20dp"
    android:insetLeft="20dp">
</inset>

【讨论】:

【解决方案6】:

与@Vivek 答案相同,但在 Kotlin 和不同的参数中

class SimpleItemDecorator : RecyclerView.ItemDecoration {

    private var top_bottom: Int = 0
    private var left_right: Int = 0

    /**
     * @param top_bottom for top and bottom margin
     * @param left_right for left and right margin
     */
    constructor(top_bottom: Int, left_right: Int = 0) {
        this.top_bottom = top_bottom
        this.left_right = left_right
    }

    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
        super.getItemOffsets(outRect, view, parent, state)
        outRect.bottom = top_bottom
        outRect.top = top_bottom
        outRect.right = left_right
        outRect.left = left_right
    }
}

【讨论】:

    【解决方案7】:

    这是一个简单的Kotlin 代码sn-p 来实现ItemDecorationRecyclerView

     recyclerView.addItemDecoration(object : RecyclerView.ItemDecoration() {
                    override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
                        outRect.left = 20    // Left Margin.
                        outRect.right = 20   // Right Margin.
                        outRect.top = 16     // Top Margin.
                        outRect.bottom = 16  // Bottom Margin.
                    }
                })
    

    解释:- 在上面的示例代码中,我们为每个项目添加边距 从所有四个方向查看 RecyclerView。

    快乐编码...

    【讨论】:

      【解决方案8】:

      下面是RecyclerView 中带左边距的分隔符代码。只需将代码粘贴到MainActivityOnCreate 方法中即可。

      class SimpleDividerItemDecoration extends RecyclerView.ItemDecoration {
          private Drawable mDivider;
      
          public SimpleDividerItemDecoration(Context context) {
              mDivider = context.getResources().getDrawable(R.drawable.divider);
          }
      
          @Override
          public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
              int left = 250;
              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);
              }
          }
      }
      
      recyclerView.addItemDecoration(new SimpleDividerItemDecoration(
                  getApplicationContext()));
      

      因为divider.xml 文件将从您的drawable 文件夹中丢失,所以下面是您在drawable 文件夹上创建分隔线布局后必须粘贴的代码。

      <?xml version="1.0" encoding="utf-8"?>
      <shape xmlns:android="http://schemas.android.com/apk/res/android"
          android:shape="rectangle">
      
        <size
          android:width="1dp"
          android:height="1dp" />
      
        <solid android:color="@color/divider" />
      
      </shape>
      

      【讨论】:

        【解决方案9】:

        我找到了最好最简单的解决方案

        <inset xmlns:android="http://schemas.android.com/apk/res/android"
               android:insetLeft="40dp"
               android:insetRight="40dp" >
            <shape>
                <size android:height="1dp"/>
                <solid android:color="@color/recyclerview_divider" />
            </shape>
        </inset>
        

        发件人:https://stackoverflow.com/a/40434249/5093308

        【讨论】:

          猜你喜欢
          • 2017-07-14
          • 1970-01-01
          • 2015-09-23
          • 1970-01-01
          • 2017-02-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-25
          • 2019-10-24
          相关资源
          最近更新 更多