android组建学习: ListView与ArrayAdapter

实验案例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等。
【实验内容】

效果图:

 

android组建学习: ListView与ArrayAdapter_第1张图片

android组建学习: ListView与ArrayAdapter_第2张图片

实验内容
练习一: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文件,使其内容如下:

    ListViewDemo
   
        费德勒
        纳达尔
        德约科维奇
        穆雷
   


其中,字符串数组就是要显示的数据。

3.设置主布局文件
    修改主布局文件activity_main.xml,在其中添加ListView组件,并设置其相关属性,具体内容如下。


    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
            android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="网球运动员:"
        android:textSize="20sp"
        android:textColor="#FF0000"
        />

            android:layout_width="fill_parent"
        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组件,并设置其相关属性。具体如下:

    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
            android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="网球运动员:"
        android:textSize="20sp"
        android:textColor="#FF0000"
        />
            android:id="@+id/lv"
        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 adapter = new ArrayAdapter(this, android.R.layout.simple_expandable_list_item_1,strs);
        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_width="match_parent"
    android:layout_height="match_parent"   >

            android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true" 
        android:textSize="18sp" />

            android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="测试" />


在这个列表项目布局中,每个项目加了一个按钮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 adapter = new ArrayAdapter(this, R.layout.listitem,R.id.item,strs);
        listview=(ListView)findViewById(R.id.lv);
        listview.setAdapter(adapter);
    }
}

其实,只修改了一条语句,即:
ArrayAdapter adapter = new ArrayAdapter(this,
 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_width="match_parent"
    android:layout_height="match_parent" 
android:descendantFocusability="blocksDescendants"   >

            android:id="@+id/item"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true" 
        android:textSize="18sp" />

            android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="测试" />

    添加了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 adapter = new ArrayAdapter(this, R.layout.listitem,R.id.item,strs);
        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

 

 

你可能感兴趣的