—— 如果我这样就倒下了,那么我也不过是这种程度的男人罢了。 ——索隆
ListView是什么
ListView是一个可以滑动的列表控件,当我们需要以列表的方式显示数据时,特别是大量的数据时,我们可以使用ListView控件,比如我们常见的通讯录列表、微信聊天列表、朋友圈列表等。
ListView有什么用
ListView用来展示大量的数据列表时具有很好的灵活性和性能,这里需要提到的是,Android还提供了一个更灵活性和更高性能的列表控件RecycleView(这个在后面的篇章会详细说明)。
ListView怎么用
1. ArrayAdapter
ArrayAdapter专门用来显示只有一个TextView的数据列表项。这点可以从ArrayAdapter的源码看出来。这里截取其中一小段说明:
1
2
3
4
5
6
7
8
|
final TextView text; if (mFieldId == 0 ) { // 如果没有指定显示数据的控件,那就把整个布局view转换成TextView text = (TextView) view; } else { // 如果有指定,那就实例化 text = view.findViewById(mFieldId); } |
我们来看ArrayAdapter的具体用法,新建activity_main.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<? xml version = "1.0" encoding = "utf-8" ?> < androidx.constraintlayout.widget.ConstraintLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < ListView android:layout_width = "match_parent" android:layout_height = "match_parent" android:divider = "#EEEEEE" android:dividerHeight = "1dp" /> </ androidx.constraintlayout.widget.ConstraintLayout > |
然后在MainActivity中实例化:
1
|
ListView listView = (ListView) findViewById(R.id.listview); |
实例化了ListView之后给ListView装载数据,即实例化数据适配器Aadapter:
1
2
3
4
|
String[] data = { "赵一" , "刘二" , "张三" , "李四" , "王五" , "赵六" , "韩梅梅" , "李雷" , "小明" , "小红" , "小张" , "小赵" , "小刘" , "小往" , "小韩" , "小李" , "小孙" , "小钱" }; ArrayAdapter<string> array = new ArrayAdapter<>( this , android.R.layout.simple_list_item_1, data); listView.setAdapter(array); </string> |
运行看效果:
2. SimpleAdapter
SimpleAdapter相对于ArrayAdpter展示只有一个TextView的数据列表项多了ImageView的数据列表项。这个看源码也可以看得出。这里截取其中一小段说明:
1
2
3
4
5
6
7
8
9
10
11
|
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); } } |
我们来看SimpleAdapter的具体用法,修改MainActivity代码为:
1
2
3
4
5
6
7
8
9
10
|
ArrayList<map<string, string= "" >> list = new ArrayList<>(); Map<string, string= "" > hashMap = null ; for ( int i = 0 ; i < 20 ; i++) { hashMap = new HashMap<>(); hashMap.put( "name" , "第" + i + "个item" ); list.add(hashMap); } SimpleAdapter simple = new SimpleAdapter( this , list, R.layout.item_listview, new String[]{ "name" }, new int []{R.id.tv_name}); listView.setAdapter(simple); </string,></map<string,> |
运行效果:
3. 自定义BaseAdaper
自定义BaseAdapter可以展示任意类型的数据列表项,其实上面SimpleAdapter和ArrayAdapter都是继承自BaseAdapter,区别在于getView方法,SimpleAdapter和ArrayAdapter的getView读者可以自行查看源码,基本和上面截取的一小段差不多。我们来看自定义BaseAdapter的用法:
1
2
3
4
5
6
|
List<string> list = new ArrayList<>(); for ( int i = 0 ; i < 20 ; i++) { list..add( "第" + i + "个item" ); } listView.setAdapter( new MyAdapter(list)); </string> |
其中MyAdapter类的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
class MyAdapter extends BaseAdapter { private List<string> mList; public MyAdapter(List<string> mList) { this .mList = mList; } @Override public int getCount() { return mList == null ? 0 : mList.size(); } @Override public String getItem( int position) { return mList.get(position); } @Override public long getItemId( int position) { return position; } @Override public View getView( int position, View convertView, ViewGroup parent) { ViewHolder holder = null ; //判断是否缓存 if (convertView == null ) { holder = new ViewHolder(); //通过LayoutInflater实例化布局 convertView = mInflater.inflate(R.layout.item_listview, null ); holder.tvName = (TextView) convertView.findViewById(R.id.tv_name); convertView.setTag(holder); } else { //通过tag找到缓存的布局 holder = (ViewHolder) convertView.getTag(); } //设置布局中控件要显示的视图 holder.tvName.setText(mList.get(position)); return convertView; } public final class ViewHolder { public TextView tvName; } } } </string></string> |
运行效果: