在添加listview的 addheader方法时报错如下:
android.widget.RelativeLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParam
在main.xml文件中、
<FrameLayout android:layout_width="fill_parent" android:layout_height="wrap_content"
android:id="@+id/online_album_detail_frame"
android:layout_alignParentTop="true"
>
</FrameLayout>
<ListView> ***** </Listview>
我是将ListView上面的FrameLayout直接设置为listview的header。结果报错,原因:
在ListView源码里可以看到:
1 void resetList() {
2 // The parent's resetList() will remove all views from the layout so we need to
3 // cleanup the state of our footers and headers
4clearRecycledState(mHeaderViewInfos);
5 clearRecycledState(mFooterViewInfos);
7 super.resetList();
9 mLayoutMode = LAYOUT_NORMAL;
10 }
12 private void clearRecycledState(ArrayList<FixedViewInfo> infos) {
13 if (infos != null) {
14 final int count = infos.size(); 15
for (int i = 0; i < count; i++) {
17 final View child = infos.get(i).view;
18 final LayoutParams p = (LayoutParams) child.getLayoutParams();
19 if (p != null) {
20 p.recycledHeaderFooter = false;
}
}
}
}
错误就是在第18行抛出的,这里的 mFooterViewInfos 实际上就是我们添加的Footer view的一个列表。代码里循环处理每个footer view,而在getLayoutParams()时,ListView要求必须是AbsListView的LayoutParams
修改Framelayout的LayoutParams为 AbsListView.LayoutParams同样报错,这是为什么呢?
因为在main.xml文件中一样用到了FrameLayout ,将其Params设置为AbsListview的Params 那么,外层嵌套的parent不能识别。
同样报cast 类型错误。
解决办法:
将FrameLayout 提取出来,放到一个单独的xml文件中
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/online_album_detail_imageview"
android:layout_alignParentLeft="true"/>
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content"
android:id="@+id/online_album_detail_tv"
android:maxLines="2"
android:textSize="@dimen/text_size_medium"
android:layout_below="@+id/online_album_detail_imageview"
android:layout_centerVertical="true"
android:background="@color/online_list_bg"
android:layout_marginLeft="10dp"
android:ellipsize="end"
android:layout_gravity="bottom"
/>
</FrameLayout
在代码中
通常添加头部的方法是 1 | LayoutInflater lif = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
2 | View headerView = lif.inflate(R.layout.header, null ); |
3 | mListView.addHeaderView(headerView); |
但是 lif.inflate(R.layout.header, null)丢失了XML布局中根View的LayoutParam,应该使用的是
1 | lif.inflate(R.layout.header, mListView, false ); |
最常用的一个方法:
1 | View inflate( int resource, ViewGroup root, boolean attachToRoot) |
其中:
resource 是布局文件ID
root 是父ViewGroup对象,
attachToRoot 是是否将“翻译”出来的View添加到上面的root中
root和attachToRoot是共同作用的:
1,有root,同时attachToRoot为false,那么inflate()返回的就是“翻译”得到的view
2,有root,同时attachToRoot为true,那么inflate()就是将“翻译”得到的view添加到root后,然后返回root
3,无root,同时attachToRoot为false,那么inflate()返回的就是“翻译”得到的view。
4,无root,同时attachToRoot为true,报错。
另外,root还有一个重要的作用就是为“翻译”得到的view添加合适的LayoutParam,并且如果并不想将得到的View添加到root的话,传递何种root是并没有要求的,比如:
1 | View view = mLayoutInflater.inflate(R.layout.header, new ListView(mContext), false ); |
2 | View view = mLayoutInflater.inflate(R.layout.header, new LinearLayout(mContext), false ); |
3 | View view = mLayoutInflater.inflate(R.layout.header, new RelativeLayout(mContext), false ); |