中心水平最后一行使用span Recycler GridLayoutManager

时间:2016-12-20 11:22:44

标签: android android-recyclerview gridlayoutmanager

我正在尝试在回收站视图中将最后一行中心的项目设为水平。我正在使用GridLayoutManager来实现功能。使用setSpanSizeLookup,我想根据SO上的帖子调整最后一行的跨度大小,但遗憾的是我无法跟踪当前正在填充的行,因此我的逻辑无效。

我想要实现的目标是:

enter image description here

代码:

static private int NUM_OF_COLUMNS = 3;

final GridLayoutManager manager = new GridLayoutManager(getBaseActivity(), NUM_OF_COLUMNS);

        manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {

            int rowNum = 0;

            @Override
            public int getSpanSize(int position) {

                int spanSize = 1;

                if(position == 0)
                    rowNum = 0; //reset it

                //check if it is last row
                int numOfRows = (int) Math.ceil((double) list.size() / NUM_OF_COLUMNS);
                if(rowNum == numOfRows - 1) {
                    //get num of items in last row
                    int items = list.size() - (NUM_OF_COLUMNS * rowNum);
                    if(items == 1)
                        spanSize = 3;
                }

                if(rowNum % NUM_OF_COLUMNS == 0) //if last element
                    rowNum++;

                return spanSize;
            }
        });

        recyclerView.setLayoutManager(manager);

上面的代码是管理行号,因为我不知道如何获取网格的当前行和列位置。有人能指向正确的方向吗?感谢。

2 个答案:

答案 0 :(得分:4)

看看this。这是谷歌库,它将CSS灵活盒布局模块的类似功能带到了Android。

活动中的

  FlexboxLayoutManager layoutManager = new FlexboxLayoutManager();
        layoutManager.setFlexWrap(FlexWrap.WRAP);
        layoutManager.setFlexDirection(FlexDirection.ROW);
        layoutManager.setAlignItems(AlignItems.CENTER);
        viewDecks.setLayoutManager(layoutManager);
在Adapter.ViewHolder中

ViewGroup.LayoutParams lp = itemView.getLayoutParams();
            if (lp instanceof FlexboxLayoutManager.LayoutParams) {
                FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
                flexboxLp.setFlexGrow(1.0f);
                flexboxLp.setAlignSelf(AlignSelf.CENTER);
            }

并确保设置android:layout_gravity="center"

答案 1 :(得分:0)

我相信,有了适配器中已知数量的项目,就可以为GridLayoutManager类编写简单的扩展名了。

我只需要这个,所以这里是可行的解决方案...

/**
 * Get grid layout manager with special optimization for span of the last row.
 * In case, last row won't have same number of items as previous rows, its content
 * will be spread over whole row.
 *
 * @param ctx current context
 * @param spanCount number of items per row
 * @param itemsCount number of items in adapter
 * @param orientation manager orientation
 * @param reverseLayout flag for orientation direction
 */
fun getGridManagerLastRowCenter(ctx: Context, spanCount: Int, itemsCount: Int,
        @RecyclerView.Orientation orientation :Int, reverseLayout: Boolean)
        : GridLayoutManager {

    // get number of items in last row
    val lastRowCount = itemsCount % spanCount
    if (lastRowCount == 0) {
        return GridLayoutManager(ctx, spanCount, orientation, reverseLayout)
    }

    // number of rows with all items
    val fullRows = itemsCount / spanCount
    // "span" counter for whole row (as minimum divider)
    val rowSpan = spanCount * lastRowCount
    // span value for item in the first rows
    val baseRowItemSpan = rowSpan / spanCount
    // span value for item in the last row
    val lastRowItemSpan = rowSpan / lastRowCount

    // return generated manager
    return GridLayoutManager(ctx, rowSpan, orientation, reverseLayout).apply {
        spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() {

            override fun getSpanSize(position: Int): Int {
                return if (position / spanCount < fullRows) {
                    baseRowItemSpan
                } else {
                    lastRowItemSpan
                }
            }
        }
    }
}

使用简单的电话

rv.layoutManager = UtilsListAco.getGridManagerLastRowCenter( ctx, 3, items.size, RecyclerView.VERTICAL, false)