最近在做一个天气预报的小课题, 其中涉及到了ListView的动态刷新, 以及如何在ListView上显示图片.
1. 在ListView上显示图片.
为了实现这个功能, 首先需要定义一个布局文件, 用于显示ListView的每个Item. 比如list_item.xml:
01 | <? xml version = "1.0" encoding = "utf-8" ?> |
02 | < LinearLayout xmlns:android = "http://schemas.android.com/apk/res/android" |
03 | android:layout_width = "fill_parent" android:layout_height = "fill_parent" > |
05 | < ImageView android:id = "@+id/list_image" |
06 | android:layout_marginTop = "6px" android:layout_marginBottom = "6px" |
07 | android:layout_marginLeft = "6px" android:layout_marginRight = "6px" |
08 | android:layout_width = "wrap_content" android:layout_height = "wrap_content" /> |
09 | < TextView android:id = "@+id/list_text" |
10 | android:layout_marginLeft = "6px" android:layout_marginRight = "6px" android:layout_gravity = "center_vertical" |
11 | android:layout_width = "fill_parent" android:layout_height = "wrap_content" /> |
接下来需要选择一个合适的adapter, 由于系统提供的adapter都无法满足显示图片的需求(这点我并不确定), 因此在这里我自定义了一个BaseAdapter的子类:
01 | public class MyListAdapter extends BaseAdapter { |
02 | private Activity context; |
03 | private List<WeatherInfomation> list; |
05 | public MyListAdapter(Activity context, List<WeatherInfomation> list) { |
06 | this .context = context; |
11 | public View getView( int position, View convertView, ViewGroup parent) { |
12 | LayoutInflater inflater = context.getLayoutInflater(); |
13 | View itemView = inflater.inflate(R.layout.list_item, null ); |
14 | WeatherInfomation info = list.get(position); |
15 | TextView textView = (TextView) itemView.findViewById(R.id.list_text); |
16 | ImageView imageView = (ImageView) itemView |
17 | .findViewById(R.id.list_image); |
18 | textView.setText(info.getWeatherText()); |
19 | imageView.setImageBitmap(info.getWeatherBitmap()); |
24 | public int getCount() { |
29 | public Object getItem( int position) { |
30 | return list.get(position); |
34 | public long getItemId( int position) { |
可以看到, 定义BaseAdapter的子类需要重写很多方法, 其他方法都不难, 关键就是getView()方法. getView()方法返回的itemView对象用来显示ListView的一个Item. 使用
LayoutInflater类的
inflater方法可以从
ist_item.xml 文件中解析出itemView对象, 但此时不可直接将itemView返回, 还需定义itemView中的ImageView和TextView的行为. 可以将itemView理解为ImageView和TextView的父控件. 源文件中涉及的
WeatherInfomation是我定义的一个实体类, 代码如下:
01 | public class WeatherInfomation { |
05 | private Bitmap weatherBitmap; |
09 | private String weatherText; |
11 | public WeatherInfomation(Bitmap weatherBitmap, String weatherText) { |
13 | this .weatherBitmap = weatherBitmap; |
14 | this .weatherText = weatherText; |
17 | public Bitmap getWeatherBitmap() { |
21 | public void setWeatherBitmap(Bitmap weatherBitmap) { |
22 | this .weatherBitmap = weatherBitmap; |
25 | public String getWeatherText() { |
29 | public void setWeatherText(String weatherText) { |
30 | this .weatherText = weatherText; |
接下来只需要创建出
MyListAdapter对象并调用listview的setAdapter()方法就可以:
1 | infomations = new ArrayList<WeatherInfomation>(); |
2 | myListAdapter = new MyListAdapter(MainActivity. this , infomations); |
3 | listView.setAdapter(myListAdapter); |
这样就可以在listview上显示图片了.
2. 很多朋友都知道, 想要动态刷新listview中的内容, 只要调用在数据发生改变之后调用adapter的notifyDataSetChanged()方法就可以了. 这里需要注意的是所谓的"数据发生改变"到底指的是什么, 比如说如下的代码:
1 | infomations = new ArrayList<WeatherInfomation>(); |
2 | infomations.add( new WeatherInfomation()); |
此时是否满足发生了数据改变的情形? 其实是没有的!(这个问题导致我浪费了很长时间, 我怎么花了一天时间才找出无法动态刷新listview的原因, 希望可以让看到的朋友避免这个问题). adapter在android中属于MVC中的mode, 它是UI界面和数据之间的桥梁, 而此时的数据, 并不是只infomations, 而是infomations这个引用所指向的
WeatherInfomation集合, 因此重新创建一个
ArrayList<WeatherInfomation>并将其赋值给infomations改变的只是infomations的值,
而adapter关联的数据并没有发生变化. 后来我的处理代码是:
2 | infomations.add( new WeatherInfomation()); |
这样就真正改变了adapter所关联的数据了.
转自:
http://coolxing.iteye.com/blog/1207946