设置的ListView头时抛出ClassCastException不能转换的LinearLayout $的LayoutParams到AbsListView $的LayoutParams [英] ClassCastException cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams when setting ListView Header
问题描述
首先,我已经想通了,如何解决这个bug,但在这一点上我只是想知道为什么我的修补程序的工作。我跑成的情况是,我得到一个 ClassCastException异常,不能转换的LinearLayout $的LayoutParams到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)问题被固定
我的两方面问题是,为什么会出现这种情况?首先,在概念方面,那为什么当一个标题观点已经在整个事情刚刚去世的布局?是不是因为这种观点有效地试图进行布局两次:一次在头,一次用于实际的布局
?其次,为什么例外?这似乎非常非描述性的,它看起来并不像它在所有捕获的实际问题?这是不被处理,因为较低的水平功能将只是结果失败过高水平的问题的情况?
我的问题是,为什么会出现这种情况?首先,在概念方面,那为什么当一个标题观点已经在整个事情刚刚去世的布局?是不是因为这种观点有效地试图进行布局两次:一次在头,一次用于实际的布局
?
块引用>您的布局PARAMS这里快要疯了,这就是问题所在。
膨胀()
叫,分配ListView.LayoutParams
到mLayout
,因为你传递一个ListView为根。 <一href=\"http://developer.android.com/reference/android/view/LayoutInflater.html#inflate%28int,%20android.view.ViewGroup,%20boolean%29\"相对=nofollow>从文档:
根:可选视图是产生层次的父(如果attachToRoot为true),否则只是一个对象,它提供了一组的LayoutParams值的返回的层次结构的根(如果attachToRoot是假的。)
块引用>
当您使用
addView()
,它<一个href=\"http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/LinearLayout.java#1218\"相对=nofollow>检查孩子的则params的类型。如果不匹配,它转换,因为它可以最好的。它通过在<一过复制值做到这一点href=\"http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.2.2_r1/android/view/ViewGroup.java#5593\"相对=nofollow>一个新的构造。所以,你的mLayout
现在有LinearLayout.LayoutParams
连接。一旦你调用
addHeaderView()
,mLayout
现在是列表视图的孩子。其中一个在<一做的事情href=\"http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/1.5_r4/android/widget/ListView.java#1645\"相对=nofollow>的ListView#setupChild()
是这样的:
AbsListView.LayoutParams P =(AbsListView.LayoutParams)child.getLayoutParams();
这是几乎可以肯定你在哪里得到ClassCastException异常。你不能做直投这样。
其次,为什么例外?这似乎非常非描述性的,它看起来并不像它在所有捕获的实际问题?
块引用>这并不是说不好,但是你要明白布局系统是如何工作的。他们可以做一个简单的检查,只是抛出一个错误,或者如果它是不正确的日志消息?当然。能
的ListView
尽量妥善地处理这一问题的的LinearLayout
的方式做?当然。但他们没有。如果你认为它可以更好地处理这可能是值得张贴在Android开发者论坛/组/跟踪器。
First off, I've already figured out how to solve this bug, but at this point I'm just wondering why my fix works. The situation I was running into was that I was getting a
ClassCastException, cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams
when I tried to do the following (simplified for these purposes):mLayout = (LinearLayout) getLayoutInflater() .inflate(R.layout.my_header_layout, getListView(), false); mRootView.addView(mLayout); getListView().addHeaderView(mLayout); getListView().setAdapter(mAdapter);
I eventually broke it down and discovered that the issue was fixed when I removed the call to
mRootView.addView(mLayout)
My two-fold question is, why is this happening? First, on the conceptual side, why is it that when a header view is already in the layout the whole thing just dies? Is it because that view is effectively trying to be laid out twice: once for the header and once for the actual layout?
Secondly, why this exception? It seems awfully non-descriptive and it doesn't look like it captures the actual problem at all? Is this a case of a high level issue not being handled because a lower level function will just fail on the results anyway?
解决方案My question is, why is this happening? First, on the conceptual side, why is it that when a header view is already in the layout the whole thing just dies? Is it because that view is effectively trying to be laid out twice: once for the header and once for the actual layout?
Your layout params are going crazy here, that's the problem.
inflate()
is called, assigningListView.LayoutParams
tomLayout
, since you pass a ListView as the root. From the docs:root: Optional view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
When you use
addView()
, it checks the type of the child's params. If it doesn't match, it converts it as best it can. It does this by copying the values over in a new constructor. So, yourmLayout
now hasLinearLayout.LayoutParams
attached.Once you call
addHeaderView()
,mLayout
is now a child of the listview. One of the things done duringListView#setupChild()
is this:
AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();
This is almost definitely where you're getting the ClassCastException. You just can't do a straight cast like that.
Secondly, why this exception? It seems awfully non-descriptive and it doesn't look like it captures the actual problem at all?
It's not that bad, but you have to understand how the layout system works. Could they do a simple check, and just throw an error or log message if it's not right? Sure. Could
ListView
try to gracefully handle the issue the way aLinearLayout
does? Sure. But they don't.It might be worth posting on the Android Developer's forum/group/tracker if you think it could be handled better.
这篇关于设置的ListView头时抛出ClassCastException不能转换的LinearLayout $的LayoutParams到AbsListView $的LayoutParams的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!