当前位置: 首页 > 知识库问答 >
问题:

RecyclerView查看项目装饰:间距和分隔线

闻人伟
2023-03-14

下面是我如何为RecyclerView项目设置间距。它被设计用于网格和列表。间隔很有效。

我搞不懂的是如何插入分隔线。如有任何帮助,我们将不胜感激。

旁注:如果你有比我现在做的更好的方法来实现间距,我会非常感激:)

public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {

    private int numOfColumns;
    private int listSize;
    private int offsetInDp;
    private boolean isGridView;
    private boolean canScrollHorizontally;
    private boolean isBottomRow = false;


    public ItemOffsetDecoration(RecyclerView.LayoutManager manager, int listSize, int offsetInDp) {
        this(manager, 1, listSize, offsetInDp);
    }

    public ItemOffsetDecoration(RecyclerView.LayoutManager manager, int numOfColumns, int listSize, int offsetInDp) {
        this.numOfColumns = numOfColumns;
        this.listSize = listSize;
        this.offsetInDp = PixelConversionUtils.dpToPx(offsetInDp);

        this.isGridView = manager instanceof GridLayoutManager;
        this.canScrollHorizontally = manager.canScrollHorizontally();
    }

    @Override
    public void getItemOffsets(Rect outRect, View view,
                               RecyclerView parent, RecyclerView.State state) {

        // only do left/right spacing if grid or horizontal list
        if (isGridView || canScrollHorizontally) {
            outRect.left = offsetInDp;
            outRect.right = offsetInDp;
        }

        // only do top/bottom spacing if grid or vertical list
        if (isGridView || !canScrollHorizontally) {
            int pos = parent.getChildAdapterPosition(view);
            boolean isNotTopRow = pos >= numOfColumns;

            // Don't add top spacing to top row
            if (isNotTopRow) {
                outRect.top = offsetInDp;
            }

            int columnIndex = ((GridLayoutManager.LayoutParams) view.getLayoutParams()).getSpanIndex();

            if (pos >= (listSize - numOfColumns) && columnIndex == 0) {
                isBottomRow = true;
            }

            // Don't add bottom spacing to bottom row
            if (!isBottomRow && pos < (listSize - numOfColumns)) {
                outRect.bottom = offsetInDp;
            }
        }
    }
}

下面是我想要做的一个快速视觉效果:

以下是我所知道的:

这是我想要的:

共有3个答案

李耀
2023-03-14

哈哈……事实上,我已经试过这样做除法器了,虽然有点滑稽:首先让你用深颜色查看背景,然后让item_view背景为白色,然后为每个项目添加marginbottom-

<?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="match_parent">

<LinearLayout
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_marginBottom="2dp"
    android:layout_height="wrap_content">

    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content" />

    <TextView
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="match_parent" />

</LinearLayout>
华宪
2023-03-14

尝试放置以下 XML 代码段以获取分隔符:

<View android:layout_width="match_parent"
      android:layout_height="1dp"
      android:layout_marginLeft="72dp"
      android:layout_marginRight="16dp"
      android:background="123e4152"/>

您可以将它放在recyclerView的项目布局中您的项目下面。也可以调整页边距和背景来适应你的列表。

华景明
2023-03-14

您可以通过以下方式实现所需的外观:

>

  • 首先,创建一个可绘制的分隔符,在本例中,我使用了一个简单的形状,但您可以使用默认的线分隔符或任何其他可绘制的:

    <shape xmlns:android="http://schemas.android.com/apk/res/android" 
        android:shape="rectangle">
        <size android:height="2dp" />
        <size android:width="2dp" />
        <solid android:color="#000000" />
    </shape>
    

    其次,在<code>ItemOffsetDecoration</code>中,声明可绘制并初始化它:

    public class ItemOffsetDecoration extends RecyclerView.ItemDecoration {
    
        private Drawable mDivider;
    
        ...
    
        public ItemOffsetDecoration(...) {
            mDivider = ContextCompat.getDrawable(context, R.drawable.item_divider);
        }
    }
    

    第三,重写onDrawOver()方法:

    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
        if (isGridView) {
            drawVerticalDivider(c, parent);
        } else {
            drawVerticalDivider(c, parent);
            drawHorizontalDivider(c, parent);
        }
    
    }
    

    其中<code>drawVerticalDivider()

    public void drawVerticalDivider(Canvas c, RecyclerView parent) {
        if (parent.getChildCount() == 0) return;
    
        final int childCount = parent.getChildCount();
    
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params =
                    (RecyclerView.LayoutParams) child.getLayoutParams();
    
            int left = child.getLeft() - params.leftMargin - offsetInDp;
            int right = child.getRight() + params.rightMargin + offsetInDp;
            int top = child.getBottom() + params.bottomMargin + offsetInDp;
            int bottom = top + mDivider.getIntrinsicHeight();
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
    
    public void drawHorizontalDivider(Canvas c, RecyclerView parent) {
        final int childCount = parent.getChildCount();
    
        for (int i = 0; i < childCount; i++) {
            View child = parent.getChildAt(i);
            RecyclerView.LayoutParams params =
                    (RecyclerView.LayoutParams) child.getLayoutParams();
    
            int left = child.getRight() + params.rightMargin + offsetInDp;
            int right = left + mDivider.getIntrinsicWidth();
            int top = child.getTop() - params.topMargin - offsetInDp;
            int bottom = child.getBottom() + params.bottomMargin + offsetInDp;
            mDivider.setBounds(left, top, right, bottom);
            mDivider.draw(c);
        }
    }
    

    线性和网格布局管理器的结果:

  •  类似资料:
    • 我想得到下图所示的除法器: 我希望所有列的宽度相同,但行间距不同。现在我的第一列和最后一列被剪成这样: 以下是我的< code>ItemDecoration: 我怎样才能解决这个问题?谢谢

    • 因此,在我的have中,我有回收视图,我想要我的再循环视图项目之间的间隔,所以这里我有两个选项 < li >我可以子类化< code > RecyclerView。ItemDecoration < li >我可以将< code >边距添加到项目本身 Cleary第二个选项很简单,使用该选项我得到了想要的结果,但在网上我看到人们使用并推荐它。 我想知道使用< code>ItemDecoration是

    • 有没有办法防止分割器显示在最后一个项目之后?

    • 我有一个像这样的简单回收视图: 我在片段中的方法中添加了除法器: 我还有一个简单的适配器来保存这些项目。问题是,在我向上或向下滚动recyclerView之前,分隔线是不可见的。我试过了: 通过使用方法以编程方式滚动到最后一项和更新适配器中的项后的第一项。 添加NestedScrollView作为父级并滚动 通过对scrollView进行编程。 没什么帮助。分隔符仅在物理滚动后可见。最奇怪的是,我

    • 我正在做一个小应用程序并使用,但当我在API 19上模拟我的应用程序时,项目之间的差距很小,但是如果我在API 22上运行相同的应用程序,则没有差距(最后有一个屏幕)。 我正在使用材料设计 frag_home xml item_card xml 这是图片,左边是API 22,右边是API 19

    • 我正在构建一个使用的Android应用程序。我想将分隔符添加到,我用下面的代码做到了这一点: 到目前为止,一切正常。然而,分隔线占据了全屏幕的大小,我想给它增加边距。有没有什么方法可以给分隔线添加边距,方法是给绘制的矩形添加一些空间,而不是创建一个带边距的自定义可绘制形状,并将其添加到< code > recycle view 中?