我和此帖中的问题相同:
RecyclerView GridLayoutManager: how to auto-detect span count?
但是对于交错 GridLayoutManager。我尝试编辑this very good answer中的代码:
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 =&gt; setSpanCount(spanCount));
有人可以帮我修改一下吗?
答案 0 :(得分: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);
}
});