4

首先,我已经想出了如何解决这个错误,但此时我只是想知道为什么我的修复工作有效。我遇到的情况是,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)

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

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

4

2 回答 2

4

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

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

  • inflate()被调用,分配ListView.LayoutParamsmLayout,因为您将 ListView 作为根传递。从文档

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

  • 当您使用addView()时,它会检查子参数的类型。如果不匹配,它会尽可能地转换它。它通过将值复制到新的构造函数中来做到这一点。所以,你的mLayout现在已经LinearLayout.LayoutParams附上了。

  • 一旦你打电话addHeaderView()mLayout现在就是列表视图的一个孩子。在此期间所做的其中一件事ListView#setupChild()是:

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

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


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

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

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

于 2013-07-30T17:47:17.593 回答
0

这一切都在声明中:

cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams

LinearLayoutAbsoluteListView有 2 种不同类型的布局,因此您需要LayoutParams使用以下内容进行设置:

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

因为现在您正在使用AbsListView-specific LayoutParams

于 2013-07-30T17:30:14.817 回答