13

我遇到了一个问题GridLayoutManger setSpanSizeLookup,当活动的方向发生变化时,我正在更改跨度计数,同时检查特定位置是否是某种类型,这在方向变化上非常有效,我唯一的问题是,我正在使用zxing库进行条形码扫描,每当单击 a 时,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;
     }
});

span基于屏幕尺寸,因此可以是 1-2、2-3 和 3-4。我重复一遍,这不会给我任何关于方向更改的错误,只有当我打开zxing
PS时才会发生错误,如果我zxing intent在我的活动正在进行时打开,则landspace不会发生崩溃。

编辑

似乎只是启动了zxing导致此问题的默认意图,我有一个启动后它的去向并且activity没有发生,作为我所做的解决方法,是我创建了一个处理延迟为 1 的扫描第二个启动好像我没有那样做,它会抛出相同的。landscapeexceptionactivitybarcodeintentexception

编辑 2

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

4

4 回答 4

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。

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

  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();
    }
    

    notifyDataSetChanged这种方式即使你忘记打电话也不会崩溃requestLayout

于 2015-08-15T08:51:10.040 回答
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)什么?

不是每次都是同一个数字吗?

于 2015-08-15T06:42:37.190 回答
0

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

我们正在使用 RecyclerView 23.0.1。希望这可以帮助某人。

于 2015-10-02T15:57:17.597 回答
0

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

zxing它在调用 & 之前intent实际调用的库是问题所在,在修改源代码以删除该特定行之后,崩溃就消失了。CLEAR_TOPstartActivityForResultzxing Intent

于 2016-12-21T14:34:54.257 回答