实验案例4-2 ListView与ArrayAdapter
【实验目的】
1.掌握ListView直接通过控件属性android:entries指定要显示的字符串数组数据的方法。
2.掌握ListView通过ArrayAdapter关联数据的方法
3.掌握自定义列表项目布局及其使用
4.掌握列表项目点击事件处理
【实验原理】
ListView控件以垂直列表的方式显示列表项目,列表项目的布局是可以根据需要进行设定的。
图1
如图1所示,此ListView中包含了从0到8,共9个列表项目,这个9个列表项目是从上往下垂直显示的。每个列表项目中,有多个控件(如图1的TextView、Button),列表项目中的控件的排列方式是指定的布局(列表项目布局)进行控制。
ListView是用来显示数据的,那么,ListView如何与要显示的数据关联呢?关联的方式有二种:
第一种方式:在ListView中直接指定。这种方式只适用于简单的字符串数组数据;
第二种方式:通过Adapter与数据关联。常用的Adapter有ArrayAdapter、SimpleAdapter、BaseAdapter等。
【实验内容】
效果图:
实验内容
练习一:ListView直接与字符串数据数据相关联 2
练习二:ListView通过ArrayAdapter关联数据 4
练习三:自定义ListView项目列表布局 6
练习四:列表项目点击事件处理 8
练习一:ListView直接与字符串数据数据相关联
图2
【练习目的】
掌握ListView直接通过控件属性android:entries指定要显示的字符串数组数据的方法。
【内容说明】
本练习的任务如下:
(1)在资源文件中创建一个字符串数组作为要显示的数据;
(2)然后在主布局文件添加ListView控件,并通过设置ListView的android:entries指定要显示的字符串数组,这样将ListView与数据相关联;
(3)在Activity中加载主布局文件,实现ListView的显示。
【练习步骤】
1.创建新项目
先建立一个空项目,如HelloWorld项目,然后进行以下修改。
2.创建显示数据
修改res/value目录下的strings.xml文件,使其内容如下:
其中,字符串数组就是要显示的数据。
3.设置主布局文件
修改主布局文件activity_main.xml,在其中添加ListView组件,并设置其相关属性,具体内容如下。
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
android:layout_height="wrap_content"
android:text="网球运动员:"
android:textSize="20sp"
android:textColor="#FF0000"
/>
android:layout_height="wrap_content"
android:entries="@array/TennisPlayer"
android:divider="#0000FF"
android:dividerHeight="1dp" />
请注意:这里选用了线性布局,在ListView中通过属性android:entries指定要显示的数据内容为字符串数组TennisPlayer。
4.编写代码
由于直接在ListView中指定了数据,不需要另外编写代码,直接使用Helloworld项目中默认的加载布局文件的代码即可。
5.验证效果
运行,便会出现如图2的效果。
练习二:ListView通过ArrayAdapter关联数据
【练习目的】
掌握ListView通过ArrayAdapter关联到数据的方法。
【内容说明】
本练习的任务如下:
(1)在主布局文件添加ListView控件,并设置其id等属性;
(2)设置列表项目的布局,(如果使用系统自带的布局文件,这步可省略);
(3)在程序代码中,创建要显示的数据,即数组数据;
(4)创建与数据、列表项目布局关联的ArrayAdapter对象;
(5)获取ListView控件对象,并将其与上一步的ArrayAdapter对象相关联;
【练习步骤】
通过ArrayAdapter实现与练习一相同的效果。
1.创建新项目
先建立一个空项目,如HelloWorld项目,然后进行以下修改。
2.设置主布局文件
在主布局文件activty_main.xml中,添加ListView组件,并设置其相关属性。具体如下:
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
android:layout_height="wrap_content"
android:text="网球运动员:"
android:textSize="20sp"
android:textColor="#FF0000"
/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:divider="#0000FF"
android:dividerHeight="1dp"
/>
3.编写代码
创建数组数据;创建ArrayAdapter对象,并将其与列表项目布局(此处使用系统自带的布局)与数组数据关联;获取ListView组件对象,并将之与ArrayAdapter对象关联。具体代码如下:
package com.example.administrator.mytoast;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private String[] strs = {"费德勒","纳达尔","德约科维奇","穆雷"};
private ListView listview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter
listview=(ListView)findViewById(R.id.lv);
listview.setAdapter(adapter);
}
}
说明:
(1)android.R.layout.simple_expandable_list_item_1,是系统自带的布局。其中,只包含一个TextView组件。
android系统为了方便开发人员,在系统中定义了很多的布局文件。系统自带布局文件所在目录,我的电脑为:
C:\Program Files\Android\Android Studio\plugins\android\lib\layoutlib\data\res\layout
系统布局文件和我们自定义的布局在写法用前缀android以示区别:
系统布局文件:android.R.layout.xxx;
用户自定义布局文件:R.layout.xxx;
(2)ArrayAdapter的构造函数
ArrayAdapter有多个构造函数,本例使用的是最常用的一种。
ArrayAdapter(Context context, int resource, T[] objects))
context:上下文
textViewResourceId:列表项目的布局文件id。对于ArrayAdapter,此列表项目布局中必须要有有一个TextView控件,用来填充数据。可以是系统自还布局,也可以是自定义布局。
objects:数据源(数组或集合)。
4.验证效果
运行,效果如图2所示。
练习三:自定义ListView项目列表布局
【练习目的】
掌握自定义项目子布局的使用
【内容说明】
本练习的任务如下:
(1)在res/layout目录下,自定义列表项目布局文件;
(2)在程序代码中,创建要显示的数据,即数组数据;
(3)创建与数据、列表项目布局关联的ArrayAdapter对象;
(4)获取ListView控件对象,并将其与上一步的ArrayAdapter对象相关联;
【练习步骤】
ArrayAdapter也可以使用自定义的列表项目布局文件。
1.自定义列表项目布局文件listitem.xml
在res/layout目录下,新建布局文件listitem.xml,其内容如下:
android:layout_height="match_parent" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="18sp" />
在这个列表项目布局中,每个项目加了一个按钮Button。
2.编写代码
将上面的代码改写成如下:
package com.example.administrator.mytoast;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends AppCompatActivity {
private String[] strs = {"费德勒","纳达尔","德约科维奇","穆雷"};
private ListView listview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter
listview=(ListView)findViewById(R.id.lv);
listview.setAdapter(adapter);
}
}
其实,只修改了一条语句,即:
ArrayAdapter
R.layout.listitem, R.id.item, strs);
说明:
ArrayAdapter构造函数之一:
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
Context:上下文
Resource:包含一个TextView控件的布局文件的资源ID
textViewResourceId:在布局文件中被填充的TextView的Id
objects:数据源,可以是一个数组或一个List
3.验证效果
运行,得到如图3的效果
图3
练习四:列表项目点击事件处理
【练习目的】
掌握列表项目点击事件处理及其实现
【内容说明】
如果想要在上面的实现列表项目的点出事件处理,可以通过监听器对点击事件进行监听,来实现对列表项目被点击时,进行对应的事件处理。
下面实现,当列表中的某一项被点击时,弹出提示框中显示:点出了第*项,文本内容为***,ID为*
【练习步骤】
1.设置项目子布局文件
在前面的项目布局文件listitem.xml中,添加一个属性。具体如下:
android:layout_height="match_parent"
android:descendantFocusability="blocksDescendants" >
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="18sp" />
添加了android:descendantFocusability="blocksDescendants"
为什么要添加这个属性呢?
因为项目布局文件中,包含了Button这个同样需要监听点击事件的组件,android:descendantFocusability属性是用于设置当一个为view获取焦点时,定义viewGroup和其子控件两者之间的关系。对于本例,即用于设置列表项item与其中的子控件Button两者之间获取焦点的关系。
此属性的值有三种:
beforeDescendants:viewgroup会优先其子类控件而获取到焦点
afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点
blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点
如果列表项目布局中,没有Button,只有一个TextView控件,则可不加此项。
2.编写代码
本例在前面代码的基础上,加上事件处理代码,本例的事件处理是通过匿名内部类的方式实现。具体代码如下:
package com.example.administrator.mytoast;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private String[] strs = {"费德勒","纳达尔","德约科维奇","穆雷"};
private ListView listview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter
listview=(ListView)findViewById(R.id.lv);
listview.setAdapter(adapter);
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
//通过view获取其内部的组件,进而进行操作
String text = (String) ((TextView)view.findViewById(R.id.item)).getText();
//大多数情况下,position和id相同,并且都从0开始
String showText = "点击第" + position + "项,文本内容为:" + text + ",ID为:" + id;
Toast.makeText(MainActivity.this, showText, Toast.LENGTH_LONG).show();
}
});
}
}
说明:
onItemClick(AdapterView> parent, View view, int position, long id)
parent:用户所点击的AdapterView,这个参数一般不用。
view:当前点击的列表项所对应的布局View对象,可通过这个参数获得相应的列表项内部的组件,进而对其进行操作。举个例子,假设有一个ListView,含有4个列表项,你点了第2个,那么通过view你就可以操作第2个列表项里面的TextView、ImageView等等的组件(假设存在)。
position:当前点击的列表项的位置,从0开始,也就是点击第n个,position就是n-1。
id:当前点击的列表项的序号,也是从0开始,一般情况下position和id是一样的。
3.验证效果
运行,点击某一项,效果如图4所示。
图4