ListView加载数据方式
ListView加载的数据结构有两种类型:
(1)简单数组类型 array,List结构等
(2)List<Map<?,Object>> 结构
对于ListView只是加载简单的文本数据的话,可以选择数组结构数据.
举例如下:
举例如下:
public class MainActivity extends Activity {
private ListView listView;
private String array[] = new String[] { "语文", "英语", "数学", "化学", "物理", "英语",
"化学", "物理", "英语", "化学", "物理", "英语", "语文", "英语", "数学", "化学", "物理",
"英语", "化学", "物理", "英语", "化学", "物理", "英语" };
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) this.findViewById(R.id.listView);
listView.setAdapter(new ArrayAdapter<string>(this,
android.R.layout.simple_list_item_1, array));
}
}
</string>
这里使用的适配器为最简单的ArrayAdapter,传递的数据为数组结构,当然也可以是List集合结构,或者从arrays.xml文件中读取的数组数据都可以. android.R.layout.simple_list_item_1为系统定义该项文本内容的样式,当然你可以选择其他系统样式,或者自己定义。
对于ListView加载复杂的数据,最大也就是文本+图片而已.这时我们可以选择List<Map<?,Object>>结构来获取数据.
举例如下:
举例如下:
package com.example.listviewtest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class SecondActivity extends Activity {
private ListView listView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) this.findViewById(R.id.listView);
initData();
}
private void initData() {
// 加载稍微复杂项数据,选用SimpleAdapter
//List<Map<string object="">> list.size()就是项数,里面的map集合则是对应项的内容数据
//R.layout.item是ListView中每一项的 内容布局,需要将 每一项的map填充到 该项组件中去
BaseAdapter adapter = new SimpleAdapter(this, getData(), R.layout.item,
new String[] { "iconId", "content" }, new int[] { R.id.icon,
R.id.content });
listView.setAdapter(adapter);
}
private List<Map<string object="">> getData() {
String stringArray[] = new String[] { "日程安排", "我的客户", "客户意向", "客户意见",
"统计数据", "常用联系人" };
Integer intArray[] = new Integer[] { R.drawable.a, R.drawable.b,
R.drawable.c, R.drawable.d, R.drawable.e, R.drawable.f };
List<Map<string object="">> data = new ArrayList<Map<string object="">>();
Map<string object=""> map = null;
for (int i = 0; i < Math.min(stringArray.length, intArray.length); i++) {
map = new HashMap<string object="">();
map.put("iconId", intArray[i]);
map.put("content", stringArray[i]);
data.add(map);
}
return data;
}
}
</string></string></string></string></string></string>
每项数据item.xml布局文件内容如下:
必须要自定义Adapter,在getView里获取每项布局,设置其布局参数,关键代码如下:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="60dip" android:gravity="center_vertical">
<imageview android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentleft="true" android:layout_marginleft="20dip" android:src="@drawable/a">
<textview android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginleft="20dip" android:layout_torightof="@+id/icon" android:text="this is a">
<imageview android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignparentright="true" android:layout_marginright="20dip" android:src="@drawable/btn_open">
</imageview></textview></imageview></relativelayout>
分析知道:要设置ListView每项数据的高度,就不能将该RelativeLayout中的Layout_height设置为fill_parent或者wrap_content(此两种效果相同),而是写出具体的值.那么问题来了?如果我要实现奇数项和偶数项的高度不同咧!实现效果图如下:
必须要自定义Adapter,在getView里获取每项布局,设置其布局参数,关键代码如下:
public View getView(int position, View convertView, ViewGroup parent) {
return createViewFromResource(position, convertView, parent, mResource);
}
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {
ViewGroup v;
if (convertView == null) {
v = (ViewGroup) mInflater.inflate(resource, parent, false);
} else {
v = (ViewGroup) convertView;
}
int height = 180;
switch (position) {
case 0:
case 2:
case 4:
height = 100;
}
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
new ViewGroup.LayoutParams(-1, height));
v.setLayoutParams(params);
bindView(position, v);
ViewGroup.LayoutParams lp = v.getLayoutParams();
Log.i("test", position + ":" + lp.width + ":" + lp.height);
return v;
}
运行结果截图如下:
通过查看ListView加载复杂数据知,无非也就是在ListView数据项中添加 textView,ImageView,Checkable等类型数据,通过查看SimpleAdapter的bindView()方法就可以看出,该模块部分代码如下:
if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the
// bottom of these
// ifs since a lot of views are TextViews (e.g.
// CheckBoxes).
setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass()
.getName()
+ " should be bound to a Boolean, not a "
+ (data == null ? "<unknown type="">"
: data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the
// bottom of these
// ifs since a lot of views are TextViews (e.g.
// CheckBoxes).
setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(
v.getClass().getName()
+ " is not a "
+ " view that can be bounds by this SimpleAdapter");
}
</unknown>
加载其他类型组件,就需要自定义适配器了.通过上面代码,也可以看出我们给ImageView传递什么样的数据,为什么是Integer(int)型数据,当然也可以是String类型(最后还是要将String转换成Integer). 因为 ImageView会调用setImageResource(value);方法来给ImageView赋值。在这里,我们ListView的基础用法就讲解完了,后面我们还讨论ListView的样式设计、应用场景、以及源码分析和优化等多个方面一起探讨ListView,敬请关注! 同时,也欢迎大家和我一起学习探讨,一起提高!