概要
这节课主要讲了控件ListView
还有与其配套的适配器,ArrayAdapter
和SimpleAdapter
。还讲了一个形状(shape)Drawable
。
ListView的用法简介
ListView
顾名思义,就是列表视图,用于显示一系列布局相同的项目(item)。但是Google在设计ListView
时,并没用直接用他来管理显示的项目,而是使用适配器(Adapter)来管理每个项目的数据和界面,并使用listView.setAdapter()
方法给ListView
设置相应的适配器。
- ListView显示静态数据
在ListView
的布局文件中,有一个android:entries
属性,可以指向一个数组资源,那么数组资源又怎么定义的呢- 新建数组资源
-
我们在values文件夹点右键,选择New->Values resource file。File name 为
array.xml
在根元素
<resources></resources>
中加入<string-array name="数组名"></string-array>
节点。在其中可以添加任一个item
,格式为<item>我是一个item</item>
。整体看起来是这个样子的
-
- 新建数组资源
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="array1">
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>
1. 引用方法
这个就很简单了,在xml中引用格式为@array/数组名
。在java中引用格式为R.array.数组名
。
知道怎么定义数组资源,我们在回过头来说android:entries
这个属性,我们只要给他指向一个数组资源就行了,完整的布局文件如下
<?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="match_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:entries="@array/array1" />
</LinearLayout>
这样,我们不需要在java文件中写任何代码,就可以让ListView
带有数据啦
- ListView显示动态数据
既然是显示动态的数据,肯定要在java文件中写一些代码了。这是我们的适配器(Adapter)就闪亮登场了~
适配器有一个基类BaseAdapter
,它是一个抽象类。如果我们ListView
的item布局、数据很复杂,我们就可以通过继承BaseAdapter
,重写它的方法,来实现我们的自定义Adapter。
当我们没有那么复杂的需求时,比如我们只想显示一行文字,我们可以用ArrayAdapter
,当我们要显示一些不同的图片,文字时,我们就可以用更高级的SimpleAdapter
。而这些类正是继承自BaseAdapter
,只不过Google已经给我们写好了,拿来直接用就可以了。- ArrayAdapter使用方法
- 创建数据集
我们可以使用数组(Object[]
)或是动态数组(List
)来存放数据
- 使用普通数组,数据不能增加、删除
- 创建数据集
- ArrayAdapter使用方法
String[] data = new String[100];
for (int i = 0; i < 100; i++) {
data[i] = "第" + i + "条数据";
}
- 使用动态数组,数据可以增加、删除
List<String> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("第" + i + "条数据");
}
2. 指定item的布局
要显示一行文本,系统并不知道怎么显示,比如文字的大小,颜色等。所以我们要为item创建一个布局文件,在其中定义好我们需要的文字样式。当我们没有特殊需求时,我们则可以指定系统内置的布局文件。
- 使用系统内置的布局文件
这个很简单,我们只要使用android.R.layout.simple_list_item_1
作为我们item的布局文件就好了。其显示效果在android 4.4如图
- 使用自定义的布局
我们新建一个布局,根元素为
TextView
就好,然后给他设置属性就好了,比如我们给他指定字体为红色,大小为50sp
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="1111"
android:textColor="#f00"
android:textSize="50sp">
</TextView>
- 创建ArrayAdapter
前两步完成后,这一步就很简单了,我们只要使用
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
Context 上下文,
int 布局文件id,
List<String> 数据)
这样的格式去创建Adapter就好了。比如这样
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_list_item_1,
data);
- 设置适配器
最后调用listView.setAdapter(adapter);
就可以了,完整的代码如下
ListView listView = (ListView) findViewById(R.id.listView);
List<String> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
data.add("第" + i + "条数据");
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, data);
listView.setAdapter(adapter);
- SimpleAdapter使用方法
SimpleAdapter
比ArrayAdapter
功能更强大,可以指定图片,文字为数据。比如我们的item布局是这样的,一个图片,两个文字
这时候内容动态改变的控件为一个ImageView
两个TextView
。这时候该怎么做呢?- 创建数据集
int[] photo = new int[]{R.drawable.head1, R.drawable.head2};
List<Map<String, Object>> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Map<String, Object> map = new HashMap<>();
map.put("singer", "张" + i);
map.put("song", "第" + i + "首歌");
map.put("photo", photo[i % 2]);
data.add(map);
}
我们先在drawable中添加了两个图片,head1.jpg和head2.jpg
然后把它们的ID放到数组中,在填充数据时,就可以使用
photo[i % 2]
来交替添加这两条数据了。- 创建item布局
直接贴出来了,注意控件的ID
<?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="match_parent"
android:orientation="horizontal"
android:padding="16dp">
<ImageView
android:id="@+id/iv"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="@drawable/head1" />
<TextView
android:id="@+id/tv1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="周杰伦"
android:textSize="20sp" />
<TextView
android:id="@+id/tv2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="龙卷风"
android:textSize="20sp" />
</LinearLayout>
- 创建适配器
直接贴代码
SimpleAdapter adapter = new SimpleAdapter(
this,
data,
R.layout.item2,
new String[]{"singer", "song", "photo"},
new int[]{R.id.tv1, R.id.tv2, R.id.iv});
前三个参数没什么可说的,注意最后两个参数。
一个String
数组,一个int
数组,这是什么意思呢。
这个就是数据与控件的对应关系
可以用如下表格来对应
这样表示就很清楚了吧
- 给ListView设置适配器
这一步就不说了,完整代码如下
int[] photo = new int[]{R.drawable.head1, R.drawable.head2};
List<Map<String, Object>> data = new ArrayList<>();
for (int i = 0; i < 100; i++) {
Map<String, Object> map = new HashMap<>();
map.put("singer", "张" + i);
map.put("song", "第" + i + "首歌");
map.put("photo", photo[i % 2]);
data.add(map);
}
SimpleAdapter adapter = new SimpleAdapter(
this,
data,
R.layout.item2,
new String[]{"singer", "song", "photo"},
new int[]{R.id.tv1, R.id.tv2, R.id.iv});
listView.setAdapter(adapter);
最终的效果
自定义shape的方法
这个就不细说了,贴上代码,大家细细体会
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 边角的圆弧半径 -->
<corners android:radius="9dp" />
<!-- 实心填充 -->
<solid android:color="#f00" />
<!-- 描边:一般大小都是1dp -->
<stroke android:width="1dp" android:color="#ff000000" />
<!-- 四周留出来的空白,和xml文件中的pad效果一样,对内起作用 -->
<padding android:bottom="30dp" android:left="20dp" android:right="30dp" android:top="20dp" />
<!-- 背景颜色渐变 -->
<gradient android:angle="90" android:endColor="#ff00ff00" android:startColor="#ff0000ff" />
</shape>
补充链接
Java集合类详解
Java中HashMap详解
Java ArrayList详细介绍(示例)
Listview绘制原理与Adapter
BaseAdapter的逗逼、普通、文艺写法
Android shape的使用详解以及常用效果