android - GridLayoutManager spanSizeLookup 错误

标签 android zxing android-recyclerview gridlayoutmanager

我在使用 GridLayoutManger setSpanSizeLookup 时遇到问题,当 Activity 的方向发生变化时,我正在更改跨度计数,同时检查特定位置是否为某种类型,这对方向改变非常有效,我唯一的问题是,我正在使用 zxing 库进行条形码扫描,每当单击 button 时,我都会打开 zxing 默认 Intent 并从中检索日期,但是当 zxing 打开时它会转到 landscape 而我当前的 Activity 方向是 portrait 这给了我布局管理在仅打开 Xzing Intent 时抛出的 IllegalArgumentException,崩溃日志是这样的
java.lang.IllegalArgumentException:位置 0 的项目需要 2 个跨度,但 GridLayoutManager 只有 1 个跨度。
如果我旋转手机,这个问题不会发生,只会在我启动 Xzing Intent 时发生,我无法真正弄清楚如何解决这个问题,因为它困扰着我。这是我的 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
时才会发生错误 P.S 如果我在 landspace 上打开 zxing intent,则不会发生崩溃。

编辑

似乎只启动了 zxing 默认 Intent 导致了这个问题,我有一个 activity 在它启动后 landscape并且 exception 没有发生,正如我所做的解决方法一样,我创建了一个 activity 来处理 barcode 扫描延迟1 秒启动 intent 就像我没有那样做一样,它会抛出相同的 exception

编辑2

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

最佳答案

这是在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. ,这种方式也不会崩溃

关于android - GridLayoutManager spanSizeLookup 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31884809/

相关文章:

android - 单击后退键并返回到 Android 中的 Activity 后,音乐不播放

java - zxing 二维码扫描仪在 Android 上将上位转换为下位?

java - Android Espresso 测试中的 stub /模拟意图

java - 如何使 Recyclerview 与其父 View 一起滚动?

android - 如何从不同的 Activity 中接收对单个 Activity 的多个 Intent ?

java - ArrayList<String> getIntent().getStringArrayListExtra

android - 使用 Gradle 构建一个 fat aar,它将包含其他子模块作为 jar/aar

java - 在 ZXing 生成的 QR 码上删除边距/边框空间并将 ErrorCorrectionLevel 设置为 'H'?

android - 使用数据绑定(bind)突出显示选定的 recyclerview 行

android - 适配器扩展 baseadapter getview 的位置 = 0