在RecyclerView中创建最后的RecyclerView项填充空间(如果数据计数是奇数)

时间:2016-01-18 10:14:46

标签: android android-recyclerview gridlayoutmanager linearlayoutmanager

到目前为止,我一直在尝试创建一个recyclerView,但现在我遇到了一个问题。

我需要让它看起来像这样

enter image description here

我需要将其设为网格状列表,但我无法将它们并排放置。

其次,如果最后一项是“单独”,我需要最后一项填充两个空格。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

  

我需要将其设为网格状列表

您可以使用RecyclerView GridLayoutManager来实现它。例如,

// Initialize the view
recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
// Here 2 is the number of columns
GridLayoutManager llm = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(llm);
recyclerView.setHasFixedSize(true);
  

如果最后一项是“单独”

,我需要填写两个空格的最后一项

要自定义网格项,我们可以使用ItemDecoration。在您的情况下,如果它是唯一的最后一项应具有父宽度。我们可以通过检查最后一项的位置来实现这一点。

现在,代码:

活动

recyclerView=(RecyclerView)findViewById(R.id.recyclerView);
GridLayoutManager llm = new GridLayoutManager(this, 2);
recyclerView.setLayoutManager(llm);
recyclerView.setHasFixedSize(true);
recyclerView.addItemDecoration(new GridItemDecoration());
// And set adapter

<强> GridItemDecoration.java

public class GridItemDecoration extends RecyclerView.ItemDecoration
{
    private int mHorizontalSpacing = 10;
    private int mVerticalSpacing = 10;

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state)
    {
        super.getItemOffsets(outRect, view, parent, state);
        // Only handle the vertical situation
        int position = parent.getChildPosition(view);
        if (parent.getLayoutManager() instanceof GridLayoutManager)
        {
            GridLayoutManager layoutManager = (GridLayoutManager) parent.getLayoutManager();
            int spanCount, column;
            // Check the last item and is alone. Then set the parent's width
            if (position == parent.getAdapter().getItemCount() - 1 && position % 2 == 0)
            {
                spanCount = 1;
                outRect.left = mHorizontalSpacing;
                outRect.right = parent.getWidth() - mHorizontalSpacing;
            }
            else
            {
                spanCount = layoutManager.getSpanCount();
                column = position % spanCount;
                outRect.left = mHorizontalSpacing * (spanCount - column) / spanCount;
                outRect.right = mHorizontalSpacing * (column + 1) / spanCount;
            }

            if (position < spanCount)
            {
                outRect.top = mVerticalSpacing;
            }
            outRect.bottom = mVerticalSpacing;
        }
    }
}

答案 1 :(得分:1)

要设置不同的跨度计数,您可以使用 GridLayoutManager 标准函数 setSpanSizeLookup

在 Kotlin 中实现最后一项的填充屏幕宽度:

// Count of columns (I set it in integer resources for screen optimisation)
val spanCount = resources.getInteger(R.integer.column_count)

val layoutManager = GridLayoutManager(context, spanCount)
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        val isLastItem = position == adapter.getItemList().lastIndex

        return if (isLastItem) {
            /**
             * Return this for full width of screen.
             * It will be always equal 1, dividing only to avoid numbers in code.
             */
            spanCount / spanCount
        } else {
            // Return this for place item in your column.
            spanCount
        }
    }
}

另外,如果你有很多项目的复杂适配器,你可以使用这个实现,例如:

val spanCount = resources.getInteger(R.integer.column_count_profile)
val layoutManager = GridLayoutManager(context, spanCount)
layoutManager.spanSizeLookup = object : SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        val item = adapter.getItemList().getOrNull(position) ?: return spanCount
        return when (item) {
            is ScreenItem.Header -> spanCount
            is ScreenItem.Status -> spanCount
            is ScreenItem.Progress -> spanCount
            is ScreenItem.Empty -> spanCount
            is ScreenItem.Item -> spanCount / spanCount
            is ScreenItem.Load -> spanCount / spanCount
        }
    }
}

其中 ScreenItemsealed class,里面是这样的:

sealed class ScreenItem{
    object Header : ScreenItem()
    data class Status(var content: ContentItem) : ScreenItem()
    object Progress : ScreenItem()
    object Empty : ScreenItem()
    data class Item(val content: AnotherContentItem) : ScreenItem()
    object Load : ScreenItem()
}