GridLayoutManager spanSizeLookup错误

时间:2015-08-07 18:56:44

标签: android zxing android-recyclerview gridlayoutmanager

我遇到2015-03-01 08:00:00 PM GridLayoutManger的问题,当活动方向发生变化时,我会在检查特定位置是否为某种类型时更改跨度计数,这在方向上非常有效更改,我唯一的问题是,我正在使用setSpanSizeLookup库来执行条形码扫描,只要点击zxing,我就会打开button默认意图并从中检索日期,但是当zxing打开时,它会转到zxing,我当前的活动方向为landscape,这样我只需打开portrait即可获得布局管理所引发的IllegalArgumentException意图,崩溃日志就是这个 Xzing
如果我旋转手机不会出现这个问题,只有当我启动java.lang.IllegalArgumentException: Item at position 0 requires 2 spans but GridLayoutManager has only 1 spans.意图时才会发生这种情况,我无法弄清楚如何解决这个问题,因为它让我烦恼。这是我的Xzing -

spanSizeLookup

manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return adapter.getHolders().get(position).getLabelHolder() != null ? getResources().getInteger(R.integer.span) : 1; } }); 基于屏幕尺寸,因此可以是1-2,2-3和3-4。我再说一遍,这并没有给我任何方向改变的错误,只有当我打开span时才会出错 P.S如果我在活动开始zxing时打开zxing intent,则不会发生崩溃。

修改

似乎只启动导致此问题的landspace默认意图,我发现zxing activitylandscape启动后exception我发生的变通方法是,我创建了一个activity来处理barcode扫描,延迟1秒,以启动intent,好像我不这样做,它将抛出相同的exception

修改2

我刚刚发现,即使没有setSpanSpizeLookup,崩溃仍然会发生。只需致电manager.setSpanCount(getResources().getInteger(R.integer.span))

即可

4 个答案:

答案 0 :(得分:9)

以下是在GridLayoutManager.layoutChunk()

中抛出异常的源代码
final int spanSize = getSpanSize(recycler, state, pos);
if (spanSize > mSpanCount) {
    throw new IllegalArgumentException("Item at position " + pos + " requires " +
           spanSize + " spans but GridLayoutManager has only " + mSpanCount
           + " spans.");
}

你的spanSize是否大于你的spanCount?尝试调试并可能更改您的spanCount,看看它是如何工作的。

----更新----

有几种方法可以在列表和网格之间切换。

  1. 仅更改spanCount。

    更改spanCount后,您必须致电LayoutManager.requestLayout()。否则您的应用可能会崩溃。

  2. 仅更改SpanSizeLookUp。

    private class CustomSpanSize extends GridLayoutManager.SpanSizeLookup {
    
      private static final int LIST_SPAN_SIZE = 1;
      private static final int GRID_SPAN_SIZE = 2;
    
      private int mSpanSize = LIST_SPAN_SIZE;
    
      public void asList() {
        mSpanSize = LIST_SPAN_SIZE;
      }
    
      public void asGrid() {
        mSpanSize = GRID_SPAN_SIZE;
      }
    
      @Override
      public int getSpanSize(int position) {
        return mSpanSize;
      }
    }
    

    并像那样使用

    @Override
    protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
    
      mLayoutManager = new GridLayoutManager(this, 2);
    
      mCustomSpanSize = new CustomSpanSize();
      mLayoutManager.setSpanSizeLookup(mCustomSpanSize);
      RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler);
      recyclerView.setHasFixedSize(true);
      recyclerView.setLayoutManager(mLayoutManager);
    
      ...
    }
    
    public void someFunction() {
      if (changed) {
        mCustomSpanSize.asList();
      } else {
        mCustomSpanSize.asGrid();
      }
      // use this to update the layout
      mAdapter.notifyDataSetChanged();
      // or you can use this to update the layout
      mLayoutManager.requestLayout();
    }
    
    即使您忘记拨打notifyDataSetChangedrequestLayout

  3. ,这种方式也不会崩溃

答案 1 :(得分:0)

编辑:调用setSpanCount()并使其大于该跨度的数字? 也许更多的代码是有序的。

听起来它可能是并发修改错误。尽量不要在每个sé上使用延迟,而是在UI线程上运行修改。这将阻止UI尝试访问列表。

if(adapter.getHolders().get(position).getLabelHolder() != null)
    return getResources().getInteger(R.integer.column);
else 
    return 1;

那么什么是getResources().getInteger(R.integer.column)

每次都不会是相同的数字吗?

答案 2 :(得分:0)

令人惊讶的是,我遇到了同样的问题,并找到了解决方案。在使用构造函数中传递的spanCount初始化GridLayoutManager之后,我们的应用程序将崩溃。但是,如果我在构建对象后setSpanCount(),那就行了! :o

我们正在使用RecyclerView 23.0.1。希望这有助于某人。

答案 3 :(得分:0)

回答这个问题太迟了,但是在我工作的最新项目中,我遇到了同样的问题&经过一些真正的调试,我发现问题的原因是什么,但不知道为什么会导致它。

zxing图书馆intent它在调用CLEAR_TOP&之前实际调用startActivityForResult这是问题,在修改zxing Intent的源代码以删除该特定行后,崩溃消失了。