设置的ListView头时抛出ClassCastException不能转换的LinearLayout $的LayoutParams到AbsListView $的LayoutParams [英] ClassCastException cannot convert LinearLayout$LayoutParams to AbsListView$LayoutParams when setting ListView Header

查看:176
本文介绍了设置的ListView头时抛出ClassCastException不能转换的LinearLayout $的LayoutParams到AbsListView $的LayoutParams的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我已经想通了,如何解决这个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, assigning ListView.LayoutParams to mLayout, 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, your mLayout now has LinearLayout.LayoutParams attached.

  • Once you call addHeaderView(), mLayout is now a child of the listview. One of the things done during ListView#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 a LinearLayout 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆