—— 如果我这样就倒下了,那么我也不过是这种程度的男人罢了。 ——索隆
ListView是什么
ListView是一个可以滑动的列表控件,当我们需要以列表的方式显示数据时,特别是大量的数据时,我们可以使用ListView控件,比如我们常见的通讯录列表、微信聊天列表、朋友圈列表等。
ListView有什么用
ListView用来展示大量的数据列表时具有很好的灵活性和性能,这里需要提到的是,Android还提供了一个更灵活性和更高性能的列表控件RecycleView(这个在后面的篇章会详细说明)。
ListView怎么用
- ArrayAdapter
ArrayAdapter专门用来显示只有一个TextView的数据列表项。这点可以从ArrayAdapter的源码看出来。这里截取其中一小段说明:
| 12345678 | final TextView text;``if (mFieldId == ``0``) {`` ``// 如果没有指定显示数据的控件,那就把整个布局view转换成TextView`` ``text = (TextView) view;``} ``else {`` ``// 如果有指定,那就实例化`` ``text = view.findViewById(mFieldId);``} |
|---|
我们来看ArrayAdapter的具体用法,新建activity_main.xml:
| 1234567891011121314 | <?``xml version``=``"1.0" encoding``=``"utf-8"``?>``<``androidx.constraintlayout.widget.ConstraintLayout xmlns:android``=``"http://schemas.android.com/apk/res/android"`` ``xmlns:tools``=``"http://schemas.android.com/tools"`` ``android:layout_width``=``"match_parent"`` ``android:layout_height``=``"match_parent"`` ``tools:context``=``".MainActivity"``>`` ``<``ListView`` ``android:id``=``"@+id/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:
| 1234 | ``String[] data = {``"赵一"``, ``"刘二"``, ``"张三"``, ``"李四"``, ``"王五"``, ``"赵六"``, ``"韩梅梅"``, ``"李雷"``, ``"小明"``, ``"小红"``, ``"小张"``, ``"小赵"``, ``"小刘"``, ``"小往"``, ``"小韩"``, ``"小李"``, ``"小孙"``, ``"小钱"``};`` ``ArrayAdapter<string> array = ``new ArrayAdapter<>(``this``, android.R.layout.simple_list_item_1, data);`` ``listView.setAdapter(array);``</string> |
|---|
运行看效果:
- SimpleAdapter
SimpleAdapter相对于ArrayAdpter展示只有一个TextView的数据列表项多了ImageView的数据列表项。这个看源码也可以看得出。这里截取其中一小段说明:
| 1234567891011 | 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代码为:
| 12345678910 | ``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,> |
|---|
运行效果:
- 自定义BaseAdaper
自定义BaseAdapter可以展示任意类型的数据列表项,其实上面SimpleAdapter和ArrayAdapter都是继承自BaseAdapter,区别在于getView方法,SimpleAdapter和ArrayAdapter的getView读者可以自行查看源码,基本和上面截取的一小段差不多。我们来看自定义BaseAdapter的用法:
| 123456 | ``List<string> list = ``new ArrayList<>();`` ``for (``int i = ``0``; i < ``20``; i++) {`` ``list..add(``"第" + i + ``"个item"``);`` ``}`` ``listView.setAdapter(``new MyAdapter(list));``</string> |
|---|
其中MyAdapter类的代码如下:
| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | ``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> |
|---|
运行效果: