Android控件——ListView

ListView允许用户通过手指上下滑动的方式将屏幕外的数据滚动到屏幕内,同时

屏幕上原有的数据则会滚动出屏幕。

1.ListView的简单用法

新建一个ListViewTest项目,修改activity_main.xml中的代码,如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</LinearLayout>

在布局中加入ListView控件,先为ListView指定一个id,然后将宽度和高度设置为match_parent,

这样ListView就占据了整个布局的空间。

修改MainActivtity中的代码,如下所示:

//定义一个数组
    private String[] data = {"Apple","Banana","Orange","Watermelon","Pear","Grape",
            "Pineapple","Strawberry","Cherry","Mango"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /*
         * 数组中的数据不能直接传递给ListView,需要借助适配器来完成。
         * ArrayAdapter可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据
        * 传入即可。
         */
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,
                android.R.layout.simple_list_item_1, data);
        ListView listView = (ListView) findViewById(R.id.list_view);

       //调用ListView的setAdapter()方法,将构建好的适配器对象传递进去。
        listView.setAdapter(adapter);
   }
}        

上述代码中,数组的数据不能直接传递给ListView,需要借助适配器来完成。

ArrayAdapter可以通过泛型来指定要适配的数据类型,然后在构造函数中把要适配的数据传入即可。

上述的代码中,ArrayAdapter的泛型指定为String,然后在ArrayAdapter的构造函数中依次传入当前

上下文、ListView子项布局的id,以及要适配的数据。

最后,调用ListView的setAdapter()方法,将构建好的适配器对象传递进去。

2.定制ListView的界面

定义一个实体类,作为ListView适配器的适配类型,新建类Fruit,代码如下:

package com.mfeng.listviewtest;

public class Fruit {
    private String name;
    private int imageId;

    //Fruit类的构造函数
    public Fruit(String name,int imageId) {
        this.name = name;
        this.imageId = imageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImageId() {
        return imageId;
    }

    public void setImageId(int imageId) {
        this.imageId = imageId;
    }

}

Fruit类中有两个字段,name表示水果的名字,imageId表示水果对应图片的资源id。

然后需要为ListView的子项指定一个自定义的布局,在layout目录下

新建fruit_item.xml文件,代码如下所示:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ImageView
        android:id="@+id/fruit_image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/fruit_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_marginLeft="10dip" />

</LinearLayout>

在这个布局中,定义了一个ImageView用于显示水果的图片,又定义了一个TextView用于显示水果的名称。

接下来需要创建一个自定义的适配器,这个适配器继承自ArrayAdapter,并将泛型指定

为Fruit类,新建类FruitAdapter,代码如下所示:

package com.mfeng.listviewtest;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class FruitAdapter extends ArrayAdapter<Fruit> {

    private int resourceId;

    //重写父类的一组构造函数
    public FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects){
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;
    }

    //重写getView()方法,这个方法在每个子项被滚动到屏幕内的时候调用
    public View getView(int position,View convertView,ViewGroup parent) {
        //获取当前项的Fruit实例
        Fruit fruit = getItem(position);

        View view = LayoutInflater.from(getContext()).inflate(resourceId, null);

        ImageView fruitImage = (ImageView) view.findViewById(R.id.fruit_image);

        TextView fruitName = (TextView) view.findViewById(R.id.fruit_name);

        //调用setImageResource和setText()方法来设置显示的图片和文字
        fruitImage.setImageResource(fruit.getImageId());
        fruitName.setText(fruit.getName());

        //返回布局
        return view;
    }

}

FruitAdapter重写了父类的一组构造函数,用于将上下文、ListView子项布局的id和数据都传递进来。

又重写了getView()方法,这个方法在每个子项被滚动到屏幕内的时候会被调用。

在getView()方法中,首先通过getItem()方法得到当前项的Fruit实例,然后使用LayoutInflater来为

这个子项加载我们传入的布局,接着调用View的findViewById()方法分别获取到ImageView和

TextView的实例,并分别调用他们的setImageResource()和setText()方法来设置显示的图片和文字,

最后将布局返回,这样自定义的适配器就完成了。

修改MainActivity中的代码,如下所示:

public class MainActivity extends Activity {

    private List<Fruit> fruitList = new ArrayList<Fruit>();

        //初始化水果数据
        initFruits();

        FruitAdapter adapter = new FruitAdapter(MainActivity.this, R.layout.fruit_item, fruitList);

        ListView listView = (ListView) findViewById(R.id.list_view);

        listView.setAdapter(adapter);

    }

//添加一个initFruit()方法,用来初始化所有的水果数据
    private void initFruits() {
        Fruit apple = new Fruit("Apple",R.drawable.apple_pic);
        fruitList.add(apple);
        Fruit banana = new Fruit("Banana",R.drawable.banana_pic);
        fruitList.add(banana);
        Fruit orange = new Fruit("Orange",R.drawable.orange_pic);
        fruitList.add(orange);
        Fruit pineapple = new Fruit("Pineapple",R.drawable.pineapple_pic);
        fruitList.add(pineapple);
    }

上述的代码中,添加了一个initFruits()方法,用于初始化所有的水果数据。在Fruit类的构造函数

将水果的名字和对应的图片id传入,然后将创建好的对象添加到水果列表中。

3.提升ListView的运行效率

getView()方法中有一个convertView参数,这个参数用于将之前加载好的布局进行缓存,以便

之后可以进行重用。

修改FruitAdapter中的代码,如下所示:

package com.mfeng.listviewtest;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class FruitAdapter extends ArrayAdapter<Fruit> {

    private int resourceId;

    //重写父类的一组构造函数
    public FruitAdapter(Context context,int textViewResourceId,List<Fruit> objects){
        super(context, textViewResourceId, objects);
        resourceId = textViewResourceId;
    }

    //重写getView()方法,这个方法在每个子项被滚动到屏幕内的时候调用
    public View getView(int position,View convertView,ViewGroup parent) {
        //获取当前项的Fruit实例
        Fruit fruit = getItem(position);

        View view;

        ViewHolder viewHolder;

        //getView()方法中有一个convertView参数,这个参数用于将之前加载好的布局进行缓存。
        if (convertView == null) {
            view = LayoutInflater.from(getContext()).inflate(resourceId, null);
            //创建一个ViewHolder对象
            viewHolder = new ViewHolder();
            //获取fruitImage的id
            viewHolder.fruitImage = (ImageView) view.findViewById(R.id.fruit_image);
            //获取fruitNmae的id
            viewHolder.fruitName = (TextView) view.findViewById(R.id.fruit_name);
            //将ViewHolder存储在View中
            view.setTag(viewHolder);
        }else {
            view = convertView;
            viewHolder = (ViewHolder) view.getTag();
        }

        //调用setImageResource和setText()方法来设置显示的图片和文字
        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.fruitName.setText(fruit.getName());

        //返回布局
        return view;
    }

    //新增一个内部类ViewHolder,用于对控件的实例进行缓存。
    class ViewHolder {
        ImageView fruitImage;
        TextView fruitName;
    }

}

上述的代码中,新增一个内部类ViewHolder,用于对控件的实例进行缓存,当convertView为空的时候,

创建一个ViewHolder对象,并将控件的实例都存放在ViewHolder里,然后调用View的setTag()方法,

将ViewHolder对象存储在View中。

当convertView不为空的时候则调用View的getTag()方法,把ViewHolder重新取出。这样控件缓存在ViewHolder

里,就没有必要通过findViewBYId()方法来获取控件的实例了。

4.ListView的点击事件。修改MainActivity中的代码,如下所示:

 //设置ListView的监听器
        listView.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view,
                    int position, long id) {
                Fruit fruit = fruitList.get(position);
                Toast.makeText(MainActivity.this, fruit.getName(), Toast.LENGTH_SHORT).show();

            }
        });

上述的代码中,使用setOnItemClickListener()方法来为ListView注册一个监听器。

Android学习笔记(十)的更多相关文章

  1. android学习笔记十——TabHost

    TabHost——标签页 ==> TabHost,可以在窗口放置多个标签页,每个标签页相当于获得了一个与外部容器相同大小的组件摆放区域. 通过此种方式可以实现在一个容器放置更多组件(EG:通话记 ...

  2. Android学习笔记十:异步处理

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html 一:基础概念 UI线程:当Android程序第一次启动时,Android会同时启动一条主 ...

  3. 【转】Pro Android学习笔记(三十):Menu(1):了解Menu

    目录(?)[-] 创建Menu MenuItem的属性itemId MenuItem的属性groupId MenuItem的属性orderId MenuItem的属性可选属性 Menu触发 onOpt ...

  4. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

  5. 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView

    目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...

  6. 【转】 Pro Android学习笔记(七十):HTTP服务(4):SOAP/JSON/XML、异常

    目录(?)[-] SOAP JSON和XMLPullParser Exception处理 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件,转载须注明出处:http://blog. ...

  7. 【转】 Pro Android学习笔记(四十):Fragment(5):适应不同屏幕或排版

    目录(?)[-] 设置横排和竖排的不同排版风格 改写代码 对于fragment,经常涉及不同屏幕尺寸和不同的排版风格.我们在基础小例子上做一下改动,在横排的时候,仍是现实左右两个fragment,在竖 ...

  8. 【转】Pro Android学习笔记(十四):用户界面和控制(2):Text类控制

    目录(?)[-] TextView 例子1在XML中设置autoLink属性 例子2在代码中设置autoLink属性 EditText AutoCompleteTextView MultiAutoCo ...

  9. 【转】Pro Android学习笔记(十二):了解Intent(下)

    解析Intent,寻找匹配Activity 如果给出component名字(包名.类名)是explicit intent,否则是implicit intent.对于explicit intent,关键 ...

  10. 【转】Pro Android学习笔记(十):了解Intent(上)

    目录(?)[-] Intent基本含义 系统的Intent Android引入了Intent的概念来唤起components,component包括:1.Activity(UI元件) 2.Servic ...

随机推荐

  1. ae学习

    Ae           提供者CoSA 1993年1月 版本1.0 代号Egg 主要加入法人功能layered compositing with mask, effect, transforms, ...

  2. Linux 防火墙开放特定端口 (iptables)

    iptables是linux下的防火墙,同时也是服务名称.   service  iptables  status        查看防火墙状态 service  iptables  start   ...

  3. android view : 绘制

    说到绘制,其实就是如何把一个view的对象,变成手机上可视的图形.很多人总结3个过程:测量,布局,绘制.这也是所有的要显示图形的程序所应该抽象的3个步骤,测量就是测量出你view的大小,布局就是要显示 ...

  4. jquery省市联动,根据公司需求而写

    //author:guan //2015-05-25 //省市联动 //实用说明,页面引用如下js //<script src="../js/jquery-1.6.3.min.js&q ...

  5. iOS--UIView和UIWindow用法

    基础 UI(user interface)是用户界面:iOS的应用是由各种各样的UI控件组成 UIWindow就是一个窗口,学的第一个基础类,就是一个容器,可以在容器上放不同的内容,每个app都需要借 ...

  6. Installshield调用DLL的正确姿势

    脚本如下 szDllPath = SUPPORTDIR ^ "TestCom.dll";       set oMyTest = CoCreateObjectDotNet(szDl ...

  7. UE4 Windows平台部署游戏到IOS 第一部分

    UE4 Version 4.11.2 or 4.12.2 方法步骤: 1.申请IOS开发者账号,大概三个工作日左右激活. 2.下载iTunes 3.创建项目因为是在Windows平台,根据官方的提示只 ...

  8. 【 D3.js 入门系列 --- 5.1 】 做一个带坐标轴和标签的图表

    前面几节讲解了图标.坐标轴.比例等等,这一节整合这些内容做一个实用的图表.结果图如下: 代码如下所示: <html> <head> <meta charset=" ...

  9. JQuery 控制元素显示隐藏

    JS在浏览器里面做调试的时候,先在浏览器里面找到页面代码加上断点来执行.然后根据执行情况来查找部分变量是否能找到,一点一点的排查内容.可以做筛选条件 部分隐藏.默认让部分条件加上.hide 默认隐藏, ...

  10. 写一些封装part1 (事件绑定移除,圆形矩形碰撞检测)

    var EventHandle = { addEvent:function(ele,type,handle){ if (ele.addEventListener) { ele.addEventList ...