1

我和这篇文章有同样的问题:
RecyclerView GridLayoutManager:如何自动检测跨度计数?

但对于交错的GridLayoutManager。我试图从这个非常好的答案中编辑代码:

public class StaggeredGridAutofitLayoutManager extends StaggeredGridLayoutManager {
    private int mColumnWidth;
    private boolean mColumnWidthChanged = true;

    public StaggeredGridAutofitLayoutManager(Context context, int columnWidth, int orientation) {
        /* Initially set spanCount to 1, will be changed automatically later. */
        super(1, orientation);
        setColumnWidth(checkedColumnWidth(context, columnWidth));
    }

    private int checkedColumnWidth(Context context, int columnWidth) {
        if (columnWidth <= 0) {
            /* Set default columnWidth value (48dp here). It is better to move this constant
            to static constant on top, but we need context to convert it to dp, so can't really
            do so. */
            columnWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 48,
                    context.getResources().getDisplayMetrics());
        }
        return columnWidth;
    }

    public void setColumnWidth(int newColumnWidth) {
        if (newColumnWidth > 0 && newColumnWidth != mColumnWidth) {
            mColumnWidth = newColumnWidth;
            mColumnWidthChanged = true;
        }
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (mColumnWidthChanged && mColumnWidth > 0) {
            int totalSpace;
            if (getOrientation() == VERTICAL) {
                totalSpace = getWidth() - getPaddingRight() - getPaddingLeft();
            } else {
                totalSpace = getHeight() - getPaddingTop() - getPaddingBottom();
            }
            int spanCount = Math.max(1, totalSpace / mColumnWidth);
            setSpanCount(spanCount);
            mColumnWidthChanged = false;
        }
        super.onLayoutChildren(recycler, state);
    }
}

但应用程序因此错误而崩溃:

RecyclerView 正在计算布局或滚动时无法调用此方法
(链接到 line => setSpanCount(spanCount));

有人可以帮我做这个修改吗?

4

1 回答 1

0

原因

我和你有同样的问题。

其原因是“计算布局或滚动”期间的框架块方法setSpanCount(int spanCount)StaggeredGridLayoutManager

这是一个解释(在 中找到RecyclerView.java):

/**
 * This variable is incremented during a dispatchLayout and/or scroll.
 * Some methods should not be called during these periods (e.g. adapter data change).
 * Doing so will create hard to find bugs so we better check it and throw an exception.
 *
 * @see #assertInLayoutOrScroll(String)
 * @see #assertNotInLayoutOrScroll(String)
 */
private int mLayoutOrScrollCounter = 0;

所以,他们检查了它并给你一个异常:D


解决方案

当我接受时,我无法以最好的方式做到这一点,并且仍然不想使用ViewTreeObserver我更改setSpanCount(spanCount)为的解决方案:

new Handler(context.getMainLooper()).post(new Runnable() {
       @Override
       public void run() {
            setSpanCount(spanCount);
       }
});
于 2016-01-17T17:05:23.477 回答