对于每一个android开发者而言,listview无疑是最常见的一个控件,打开手机应用,几乎所有app都会应用到listview,可以想象listview 到底有多重要,下面将对listview 进行详解。
android给我们提供的一些ArrayAdapter(文字),SimpleAdapter(文字和图片及其他),CursorAdapter(数据库数据)远远不够,我们可以都过自定义ListView去设置自己想要的效果。当然listview是通过适配器去将数据显示到视图中,适配器作为中间的一个桥梁。因此需要解决的关键性问题就是怎么去获取数据,怎么去显示数据。
1.ListView的控件对象
先在layout布局文件中定义listview控件
<ListView
android:id="@+id/lv_main"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
/>
然后在MainActivity中获取到控件对象
//1. 获取ListView对象
ListView listview = (ListView)findViewById(R.id.lv_main);
2.准备数据源
在我自己模拟了一些数据,这些数据以键值对的方式添加进入集合中。
//2. 准备数据源
List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
Map<String,Object> map = new HashMap<String, Object>();
map.put("logo", R.drawable.ic_10);
map.put("title", "千千静听");
map.put("version", "版本: 8.4.0");
map.put("size", "大小: 32.81M");
list.add(map);
map = new HashMap<String, Object>();
map.put("logo", R.drawable.ic_2);
map.put("title", "时空猎人");
map.put("version", "版本: 2.4.1");
map.put("size", "大小: 84.24M");
list.add(map);
map = new HashMap<String, Object>();
map.put("logo", R.drawable.ic_4);
map.put("title", "360新闻");
map.put("version", "版本: 6.2.0");
map.put("size", "大小: 11.74M");
list.add(map);
map = new HashMap<String, Object>();
map.put("logo", R.drawable.ic_15);
map.put("title", "捕鱼达人2");
map.put("version", "版本: 2.3.0");
map.put("size", "大小: 45.53M");
//将数据添加进集合
list.add(map);
3.准备适配器
这里使用自定义适配器,把list集合和上下文通过构造器传入MyAdapter中。
MyAdapter adapter=new MyAdapter(this,list);
在这里新建一个MyAdapter.java,继承BaseAdapter,实现getCount,getItem,getItemId,getView这4个方法。当中的getView就解决了怎么去显示数据。重写这个方法
public class MyAdapter extends BaseAdapter{
Context context;
//list集合
List<Map<String, Object>> list;
//构造器
public MyAdapter(Context context,List<Map<String, Object>> list){
this.context= context;
this.list = list;
}
//传入数据集合
public void setList(List<Map<String, Object>> list) {
this.list = list;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public View getView(final int position, View convertView, ViewGroup arg2) {
LayoutInflater inflater=LayoutInflater.from(context);
View view=inflater.inflate(R.layout.item, null);
ImageView logo=(ImageView) convertView.findViewById(R.id.logo);
TextView title=(TextView) convertView.findViewById(R.id.title);
TextView version=(TextView) convertView.findViewById(R.id.version);
TextView size=(TextView) convertView.findViewById(R.id.size);
Button btn=(Button) convertView.findViewById(R.id.btn);
Map map=list.get(position);
logo.setImageResource((Integer) map.get("logo"));
title.setText((String) map.get("title"));
version.setText((String) map.get("version"));
size.setText((String) map.get("size"));
return view;
}
}
这里需要将布局文件反射成一个View对象,新建布局文件为item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginLeft="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:gravity="center_vertical"
android:padding="5dp"
android:descendantFocusability="blocksDescendants">
<!-- 用上面代码抢回焦点 -->
<ImageView
android:id="@+id/logo"
android:src="@drawable/ic_10"
android:layout_width="70dp"
android:layout_height="70dp"
/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:text="天天静听"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_marginTop="2dp"/>
<TextView
android:id="@+id/version"
android:text="版本: 8.4.0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#999"
android:layout_marginTop="6dp"/>
<TextView
android:id="@+id/size"
android:text="大小: 32.81M"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:textColor="#999"
android:layout_marginTop="6dp"/>
</LinearLayout>
<Button
android:id="@+id/btn"
android:text="安装"
android:textColor="#fff"
android:textSize="14sp"
android:layout_width="66dp"
android:layout_height="30dp"
android:background="@drawable/btn_selector"
android:layout_marginRight="5dp"/>
</LinearLayout>
4.设置适配器
//4. 将适配器关联到ListView
listview.setAdapter(adapter);```
最后这个小demo就完成了,放一下效果图
小插曲一下,如果出现listview点击事件没有反应的话,这是因为listview的焦点被button抢了,那么该怎么解决呢?先简单说2中方法解决。
(1)抢回焦点
android:descendantFocusability="blocksDescendants"
(2)设置button的属性
android:focusable="false"