天天看点

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
android组建学习: ListView与ArrayAdapter

实验内容

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

<resources>

    <string name="app_name">ListViewDemo</string>

    <string-array name="TennisPlayer" >

        <item>费德勒</item>

        <item>纳达尔</item>

        <item>德约科维奇</item>

        <item>穆雷</item>

    </string-array>

</resources>

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

3.设置主布局文件

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

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    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">

    <TextView

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="网球运动员:"

        android:textSize="20sp"

        android:textColor="#FF0000"

        />

    <ListView

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:entries="@array/TennisPlayer"

        android:divider="#0000FF"

        android:dividerHeight="1dp" />

</LinearLayout>

请注意:这里选用了线性布局,在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组件,并设置其相关属性。具体如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    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">

    <TextView

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:text="网球运动员:"

        android:textSize="20sp"

        android:textColor="#FF0000"

        />

    <ListView

        android:id="@+id/lv"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:divider="#0000FF"

        android:dividerHeight="1dp"

        />

</LinearLayout>

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<String> adapter = new ArrayAdapter<String>(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,其内容如下:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent"   >

    <TextView

        android:id="@+id/item"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerVertical="true" 

        android:textSize="18sp" />

    <Button

        android:id="@+id/button1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:text="测试" />

</RelativeLayout>

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

        listview=(ListView)findViewById(R.id.lv);

        listview.setAdapter(adapter);

    }

}

其实,只修改了一条语句,即:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(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中,添加一个属性。具体如下:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent" 

android:descendantFocusability="blocksDescendants"   >

    <TextView

        android:id="@+id/item"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerVertical="true" 

        android:textSize="18sp" />

    <Button

        android:id="@+id/button1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentRight="true"

        android:text="测试" />

</RelativeLayout>

    添加了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<String> adapter = new ArrayAdapter<String>(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

继续阅读