ListView使用遇到的问题:1. ItemView使用merge标签减少嵌套 2. getView中抛出类转换异常
2011-03-08 22:50
543 查看
1. 当自定义一个LinearLayout 的子类作为ListView的ItemView
当我们需要使用列表显示数据的时候,ListView和Adapter是必须用到的api,其中Adapter中的getView方法起着给ListView创建ItemView的作用,ItemView中如何布局,显示什么内容,都是由getView方法决定的。我们应该如何布局ItemView呢,一般的我们都会创建一个布局的子类,例如这样
R.layout.list_haha_item 布局方式如下:
这样的话,在getView中可以直接new出一个对象来使用,可使代码变的整洁。
但是这样会出现一个问题,就是HahaItem下又嵌套了一个LinearLayout,视图层上多了一层LinearLayout,而这一层是很没必要的,怎么去掉这一层呢?
目前有两种办法,一种是完全自定义HahaItem,将他做成一个类似于系统view,例如TextView等等的一个控件,这样做很好,但是很麻烦
还有一种就是使用merge标签,将xml布局中的顶层LinearLayout改成merge,同时将android:orientation="vertical" android:layout_height="wrap_content"android:layout_width="fill_parent 等属性都去掉,因为就算写上了也不起作用。
在HahaItem的setupUI方法中使用代码动态的设置它的各种属性。这样就会减少多余的LinearLayout层了。
2. 当使用代码创建一个控件时,如何设置它的layoutParams?
从下面的错误代码说起:
item.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 60)); 这样是不对的,为什么?
先看一张图:
![](http://pic002.cnblogs.com/images/2011/129165/2011030822375384.png)
从这张图上可以看出view控件自身的layoutParams是由它的parent容器决定的,也就是说给一个view设置layout属性的时候,必须设置它的父容器的layoutParams,这也就是为什么上面的代码中必须要item.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, 60));这样写才对的元婴,item的父容器是ListView,所以必须设置ListView的LayouParams。
3. ArrayAdapter的getView方法中发生的ClassCastException
说明:
1. mResource代表的xml布局文件是个复杂布局,顶层是LinearLayout,包含一个TextView
2. getView方法是ArrayAdapter中的方法
为什么会出现类转换异常?
虽然getView方法返回的是TextView,但是convertView的类型是LinearLayout,当执行 tv = (TextView) convertView;的时候就会抛出类转换异常。
TextView tv是LinearLayout中的一个子控件,他是依赖于LinearLayout存在的,虽然可以获取这个TextView对象,但是不能将他单独取出来,存放到ListView中,上面的代码,实际上存放到ListView中的ItemView是LinearLayout类型的。
这个错误很容易犯,下次注意。
当我们需要使用列表显示数据的时候,ListView和Adapter是必须用到的api,其中Adapter中的getView方法起着给ListView创建ItemView的作用,ItemView中如何布局,显示什么内容,都是由getView方法决定的。我们应该如何布局ItemView呢,一般的我们都会创建一个布局的子类,例如这样
private class HahaItem extends LinearLayout { public int id; public TextView mDate; public TextView mContent; public TextView mPublisher; public ImageView mUserIcon; public HahaItem(Context context) { super(context); setupUI(); } private void setupUI() { View.inflate(getContext(), R.layout.list_haha_item, this); mDate = (TextView) this.findViewById(R.id.haha_pubdate); mContent = (TextView) this.findViewById(R.id.haha_content); mPublisher = (TextView) this.findViewById(R.id.haha_publisher); /** * 设置中文汉字的字体为bold,在TextView中设置textstyle=bold 仅对英文字符有效,必须使用 * 下述方法设置中文的字体为bold * */ TextPaint tp = mPublisher.getPaint(); tp.setFakeBoldText(true); mUserIcon = (ImageView) this.findViewById(R.id.haha_head_img); } }
R.layout.list_haha_item 布局方式如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="fill_parent"> <TextView android:id="@+id/haha_content" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="17sp" android:textStyle="normal" android:typeface="monospace" android:paddingLeft="18dip" android:paddingRight="18dip" android:layout_marginTop="18dip" android:lineSpacingExtra="5dip" android:textScaleX="1.1" android:maxLines="5" android:layout_marginBottom="18dip" android:textColor="@color/dark_gray" /> <RelativeLayout android:id="@+id/haha_bottombar" android:layout_width="fill_parent" android:layout_height="46dip" android:background="@drawable/test" android:layout_marginTop="2dip"> <LinearLayout android:id="@+id/pub" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_alignParentLeft="true"> <ImageView android:id="@+id/haha_head_img" android:layout_width="wrap_content" android:layout_height="wrap_content" android:maxHeight="25dip" android:adjustViewBounds="true" android:maxWidth="25dip" android:baselineAlignBottom="true" android:layout_marginTop="7dip" android:layout_marginLeft="5dip" /> <TextView android:id="@+id/haha_publisher" android:layout_marginLeft="10dip" android:paddingLeft="5dip" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:textStyle="bold" android:textColor="#889db6" android:gravity="center_vertical" /> </LinearLayout> <TextView android:id="@+id/haha_pubdate" android:layout_width="wrap_content" android:layout_height="fill_parent" android:singleLine="true" android:layout_alignParentRight="true" android:textStyle="normal" android:gravity="center_vertical" android:textColor="#7b7b7b" android:layout_alignParentBottom="true" android:textSize="14sp" /> </RelativeLayout> </LinearLayout>
这样的话,在getView中可以直接new出一个对象来使用,可使代码变的整洁。
但是这样会出现一个问题,就是HahaItem下又嵌套了一个LinearLayout,视图层上多了一层LinearLayout,而这一层是很没必要的,怎么去掉这一层呢?
目前有两种办法,一种是完全自定义HahaItem,将他做成一个类似于系统view,例如TextView等等的一个控件,这样做很好,但是很麻烦
还有一种就是使用merge标签,将xml布局中的顶层LinearLayout改成merge,同时将android:orientation="vertical" android:layout_height="wrap_content"android:layout_width="fill_parent 等属性都去掉,因为就算写上了也不起作用。
在HahaItem的setupUI方法中使用代码动态的设置它的各种属性。这样就会减少多余的LinearLayout层了。
2. 当使用代码创建一个控件时,如何设置它的layoutParams?
从下面的错误代码说起:
public View getView(int position, View convertView, ViewGroup parent) { TextView item; if (convertView == null) { item = new TextView(getContext()); item.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, 60)); }else { item = (TextView) convertView; } final JiFengItemInfo info = mInfoList.get(position); item.setText(info.name); return item; }
item.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT, 60)); 这样是不对的,为什么?
先看一张图:
![](http://pic002.cnblogs.com/images/2011/129165/2011030822375384.png)
从这张图上可以看出view控件自身的layoutParams是由它的parent容器决定的,也就是说给一个view设置layout属性的时候,必须设置它的父容器的layoutParams,这也就是为什么上面的代码中必须要item.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.FILL_PARENT, 60));这样写才对的元婴,item的父容器是ListView,所以必须设置ListView的LayouParams。
3. ArrayAdapter的getView方法中发生的ClassCastException
@Override public View getView(int position, View convertView, ViewGroup parent) { TextView tv; if (convertView == null) { tv = (TextView) View.inflate(getContext(), mResource, null); } else { tv = (TextView) convertView; } JiFengItemInfo info = getItem(position); tv.setTag(getItem(position)); tv.setText(info.name); return tv; }
说明:
1. mResource代表的xml布局文件是个复杂布局,顶层是LinearLayout,包含一个TextView
2. getView方法是ArrayAdapter中的方法
为什么会出现类转换异常?
虽然getView方法返回的是TextView,但是convertView的类型是LinearLayout,当执行 tv = (TextView) convertView;的时候就会抛出类转换异常。
TextView tv是LinearLayout中的一个子控件,他是依赖于LinearLayout存在的,虽然可以获取这个TextView对象,但是不能将他单独取出来,存放到ListView中,上面的代码,实际上存放到ListView中的ItemView是LinearLayout类型的。
这个错误很容易犯,下次注意。
相关文章推荐
- ListView使用ViewPager作头布局遇到的问题及处理
- 嵌套Fragment的使用及遇到The specified child already has a parent. You must call removeView()问题的解决
- html.toHtml fromHtml遇到嵌套标签的转换问题
- 在Fragment中使用viewPager嵌套Fragment遇到的问题(双侧viewpager)
- ScrollView嵌套使用ListView时遇到,Item显示不全问题
- viewstub中使用merge遇到的问题
- 嵌套Fragment的使用及遇到The specified child already has a parent. You must call removeView()问题的解决
- listview 与 viewpager嵌套使用滑动冲突问题
- ListView嵌套RecyclerView遇到的一些坑以及解决办法
- 使用开源的PullToRefreshScrollView scrollTo和scrollby遇到的问题
- 关于Scrollview嵌套ListView,使用setListViewHeightBasedOnChildren(ListView listView) ,在小米手机上崩溃问题
- RecyclerView嵌套多个Edittext遇到的一些问题
- 在ListView中嵌套ViewFlow,ViewFlow滑动有些卡顿的问题~
- 关于使用RecyclerView遇到的一些问题集合
- Android 使用webview遇到的问题及解决办法
- iOS Autolayout情况下,ViewController嵌套时,childViewController的Frame异常问题
- Android RecyclerView的使用过程遇到的问题
- Android 解决ListView在使用多个布局的同时使用convertView进行缓存时导致ListView下面有空白的问题
- Git使用遇到的问题--merge冲突解决
- listview ,scrollview,viewpager,嵌套问题