【问题标题】:ClassCastException cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams when setting ListView Header设置 ListView Header 时,ClassCastException 无法将 LinearLayout$LayoutParams 转换为 AbsListView$LayoutParams
【发布时间】:2013-07-30 16:37:14
【问题描述】:

首先,我已经想出了如何解决这个错误,但此时我只是想知道为什么我的修复工作有效。我遇到的情况是,当我尝试执行以下操作时收到了ClassCastException, cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams(为了这些目的而进行了简化):

mLayout = (LinearLayout) getLayoutInflater()
   .inflate(R.layout.my_header_layout, 
   getListView(), false);
mRootView.addView(mLayout);
getListView().addHeaderView(mLayout);
getListView().setAdapter(mAdapter);

我最终打破了它,发现当我删除对mRootView.addView(mLayout)的调用时问题已解决

我的两个问题是,为什么会发生这种情况?首先,在概念方面,为什么当标题视图已经在布局中时,整个东西就死了?是因为该视图实际上试图布局两次:一次用于标题,一次用于实际布局?

其次,为什么会出现这个异常?它看起来非常不具描述性,而且看起来根本没有捕捉到实际问题?这是因为较低级别的函数无论如何都会在结果上失败而没有处理高级问题的情况吗?

【问题讨论】:

  • 您是否 100% 确定您没有更改任何其他内容?
  • 嗯,看来晚上休息让我健忘,我已经根据我如何能够重现然后修复这个问题更新了这个问题。

标签: android listview android-listview


【解决方案1】:

我的问题是,为什么会这样?首先,在概念方面,为什么当标题视图已经在布局中时,整个东西就死了?是因为该视图实际上试图布局两次:一次用于标题,一次用于实际布局?

您的布局参数在这里变得疯狂,这就是问题所在。

  • 调用inflate(),将ListView.LayoutParams 分配给mLayout,因为您将ListView 作为根传递。 From the docs:

root: 作为生成层次结构的父级的可选视图(如果 attachToRoot 为 true),或者只是为返回的层次结构的根提供一组 LayoutParams 值的对象(如果 attachToRoot是假的。)

  • 当您使用addView() 时,它是子参数的checks the type。如果不匹配,它会尽可能地转换它。它通过复制a new constructor 中的值来实现这一点。因此,您的 mLayout 现在附加了 LinearLayout.LayoutParams

  • 一旦您调用addHeaderView()mLayout 现在就是列表视图的子视图。在ListView#setupChild() 期间完成的其中一件事是:

    AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();

这几乎肯定是你得到 ClassCastException 的地方。你不能做这样的直接演员。


其次,为什么会出现这个异常?它看起来非常不具描述性,而且看起来根本没有抓住实际问题?

这还不错,但您必须了解布局系统的工作原理。他们可以做一个简单的检查,如果不正确就抛出错误或日志消息吗?当然。 ListView 可以像 LinearLayout 那样优雅地处理问题吗?当然。但他们没有。

如果您认为可以更好地处理它,可能值得在 Android 开发者的论坛/组/跟踪器上发布。

【讨论】:

    【解决方案2】:

    这一切都在声明中:

    cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams
    

    LinearLayoutAbsoluteListView 有 2 种不同类型的布局,因此您需要使用以下方法设置 LayoutParams

    mLayout.setLayoutParams(new AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    

    因为现在您使用的是AbsListView-特定LayoutParams

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 2021-12-20
      相关资源
      最近更新 更多