介绍ListView时,我们一定会扯到适配器那,所以我们结合适配器来介绍ListView
1.使用String-array,一般在Spinner中使用
android:entries=”@array/entry”我iListView显示数据
2.SimpleAdapter:使用率并不高
可以展示一些复杂的布局,将数据显示到控件上,有默认的,有自定义的.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*
* int resource:布局文件(承载)
* from: 通过key拿到一个String[]
* to: 放置哪一个控件上
*/
listView = (ListView) findViewById(R.id.main_list);
List<Map<String, ?>> list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Map<String, Object> map = new HashMap<>();
map.put("title", String.format(Locale.CHINA, "title %03d", i+1));
map.put("body", String.format(Locale.CHINA, "body %03d", i+1));
map.put("img","https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1472781964&di=0165125c2e3758fe06373cf80b3b67d3&src=http://img3.duitang.com/uploads/item/201608/07/20160807131622_zvBcF.jpeg");
list.add(map);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(this, list,R.layout.item,
new String[]{"title", "img"},
new int[]{R.id.item1, R.id.image});
// 实现simpleAdapter绑定网络
simpleAdapter.setViewBinder(new SimpleAdapter.ViewBinder() {
/*
* View view, Object data将data数据加载到控件view上
* return:true:修改默认的绑定:
*
* false:使用默认的绑定 String的默认直接setText minmap:setImageResource();
*/
@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
switch (view.getId()) {
case R.id.image:
ImageView imag = (ImageView) view;
String url = (String) data;
new ImageLoader(imag).execute(url);
return true;
}
return false;
}
});
listView.setAdapter(simpleAdapter);
}
3.为ListView添加头部
一般一个listView上都会有一个头部或者底部
//加上头部
View view = LayoutInflater.from(this).inflate(R.layout.header, null);
listView.addHeaderView(view);
但是这样会有一个缺点:
我们为没个item添加监听事件时,会出现这样的情况.
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
/* // 这样使用,如果加上一个header,他也会占一个position
// 这样拿到的适配器
Entry item = (Entry) myAdapter.getItem(position);
Toast.makeText(MainActivity.this, item.getText(), Toast.LENGTH_SHORT).show();*/
// 这样,
Object item = parent.getAdapter().getItem(position);
if (item instanceof Entry) {
Entry entry = (Entry) item;
Toast.makeText(MainActivity.this, entry.getText(), Toast.LENGTH_SHORT).show();
}
}
3.ListView的优化:
1.在xml中,Listview的高度必须是个定值(march-parent或者一个确定的..dp)
2. convertView的一个复用,减少布局的加载
3.减少findViewById的使用,定义一个ViewHolder做控件的一个持有,只有view为null时,才会去findViewById
1. 在xml中,Listview的高度必须是个定值(march-parent或者一个确定的..dp)
<ListView
android:id="@+id/mian_list"
android:layout_width="match_parent"
android:divider="#00f"
android:dividerHeight="2dp"
android:layout_height="match_parent"/>
因为如果ListView中android:layout_height="match_parent"
,,会根据父控件的大小控件大小.
如果android:layout_height="warp_content"
加载图片时,分两步,第一:第一次加载图片时,listview会先计算自身的高度(锁提供的所有的item高度之和)和父控件比较大小,如果小于父控件的高度,则显示listView自身的高度,如果大于就显示父控件的高度.第二步,再去进行加载显示图片.
2. convertView的一个复用,减少布局的加载
// 先判断是否有可重用的view
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent, false);
3.减少findViewById的使用
1.findViewById的每一次调用都会很耗费时间,我们应该尽量少使用.
2.所以:我们要定义一个ViewHolder做控件的一个持有,只有view为null时,才会去findViewById.
public static class ViewHolder {
private TextView text;
private ImageView imag;
public ViewHolder(View itemView) {
text = ((TextView) itemView.findViewById(R.id.item_text));
imag = (ImageView)itemView.findViewById(R.id.item_image);
}
}
在getView中:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent, false);
// 一个view承载数据
convertView.setTag(new ViewHolder(convertView));
}
ViewHolder holder = (ViewHolder) convertView.getTag();
Entry entry = list.get(position);
holder.text.setText(entry.getText());
new ImageLoader(holder.imag).execute(entry.getImagUrl());
return convertView;
}