• Android UI组件----ListView列表控件详解


    【声明】

    欢迎转载,但请保留文章原始出处→_→

    生命壹号:http://www.cnblogs.com/smyhvae/

    文章来源:http://www.cnblogs.com/smyhvae/p/3910884.html

     

    【正文】

    内容简介:

    • 1、基本的XML配置

    • 2、ListActivity

    • 3、单选和多选模式

    • 4、ListView实现图文列表

    • 5、ListView刷新分页

    一、基本的 XML配置:

    • android:cacheColorHint="#00000000"  //设置拖动背景色为透明
    • android:dividerHeight="30px"  //listview item之间的高度(即分格条的高度)
    • android:divider="@drawable/ic_launcher"  //设置listview item之间背景或者说是颜色
    • android:fadingEdge="vertical"  //上边和下边有黑色的阴影,值为none的话就没有阴影
    • android:drawSelectorOnTop="true" 点击某条记录不放,颜色会在记录的前面,成为前景色,记录上的文字被遮住,所以点击文字不放,文字就看不到(默认为false)
    • android:scrollbars="horizontal|none"  //只有值为horizontal|vertical的时候(默认也是这个值),才会显示滚动条,并且会自动影藏和显示
    • android:fastScrollEnabled="true"  //快速滚动效果,配置这个属性,在快速滚动的时候旁边会出现一个小方块,进行快速滚动,自动隐藏和显示(如果没有出现,是因为ListView item数目不够多)
    • android:listSelector="@color/pink"  //istViewl item选中时的颜色
    • android:entries="@array/citys"  //设置列表填充的内容

    在ListView中加载本地数据,有两种方式,下面举例说明:(当然了,在这之前我们需要在布局文件activity_main.xml中添加一个ListView控件)

    【方式一】:在xml文件中添加静态数据的方式:

    在res/values/string.xml文件中, 添加一组静态数据,作为列表中将要填充的内容,代码如下

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <resources>
     3     <string name="app_name">smyh005_ListView</string>
     4     <string name="action_settings">Settings</string>
     5     <string name="hello_world">Hello world!</string>
     6     
     7     <string-array name="names">
     8         <item >生命壹号</item>
     9         <item >生命壹号</item>
    10         <item >生命壹号</item>
    11         <item >生命壹号</item>
    12         <item >生命壹号</item>
    13         <item >生命壹号</item>
    14         <item >生命壹号</item>
    15         <item >生命壹号</item>
    16         <item >生命壹号</item> 
    17     </string-array>
    18     
    19 </resources>

    紧接着,在布局文件的ListView控件中,添加如下属性:

    android:entries="@array/names"

    然后设置一下ListView的其他属性。这样,运行后,就可以显示一个简单的列表了。

    【方式二】在java代码中来添加数据:

     1 public class MainActivity extends Activity {
     2     private ListView listView;
     3     @Override
     4     protected void onCreate(Bundle savedInstanceState) {
     5         super.onCreate(savedInstanceState);
     6         setContentView(R.layout.activity_main);
     7         listView = (ListView) findViewById(R.id.listView1);
     8         String[] names = { "生命壹号", "生命壹号", "生命壹号", "生命壹号", "生命壹号", "生命壹号" };
     9         //第二个参数,也可以新建一个布局文件,在这个布局文件的TextView当中设置其他属性。因为每个Item本身就是一个TextView
    10         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    11                 android.R.layout.simple_list_item_1, names);
    12         listView.setAdapter(adapter);
    13     }
    【事件处理】

    事件处理的监听器为:OnItemClickListener。

    方法举例如下:(将当前点击的那个item的文本以吐司的方式显示出来)

     1 listView1.setOnItemClickListener(new OnItemClickListener(){
     2             
     3             //ListView的列表项的单击事件 
     4             @Override
     5             //第一个参数:指的是这个ListView;第二个参数:当前单击的那个item
     6             public void onItemClick(AdapterView<?> parent, View view, int position,
     7                     long id) {
     8                 System.out.println("parent="+parent.getClass());
     9                 System.out.println("view="+view.getClass());
    10                 
    11                 //既然当前点击的那个item是一个TextView,那我们可以将其强制转型为TextView类型,然后通过getText()方法取出它的内容,紧接着以吐司的方式显示出来
    12                 TextView tv = (TextView)view;
    13                 Toast.makeText(MainActivity.this,tv.getText(),Toast.LENGTH_SHORT).show();//方法: Toast makeText (Context context, CharSequence text, int duration)                 
    14                 
    15                 System.out.println("position="+position);
    16                 System.out.println("id="+id);
    17                 
    18             }
    19             
    20  });

    上面的第12、13行代码也可以替换成下面的这行代码:(因为通过adapter的getItem方法也可以获取对应Item,返回值类型是我们之前定义好的String类型)

            Toast.makeText(MainAcivity.this, adapter.getItem(position), Toast.LENGTH_SHORT).show;

    运行效果如下:

    二、ListActivity

    (1)如果程序的窗口仅仅只需要显示一个列表,则可以让这个activity直接继承ListActivity来实现,此时已经包含了一个ListView组件,不用再重新写布局文件了。

    代码举例如下:

     1 package com.smyhvae.smyh005listview;
     2 import android.app.ListActivity;
     3 import android.os.Bundle;
     4 import android.widget.ArrayAdapter;
     5 public class SecondActivity extends ListActivity{
     6     @Override
     7     protected void onCreate(Bundle savedInstanceState) {
     8         // TODO Auto-generated method stub
     9         super.onCreate(savedInstanceState);
    10         //通过代码设置ListView中的内容
    11         String[] names = {"生命壹号","生命壹号","生命壹号","生命壹号","生命壹号","生命壹号"};
    12         //通过ArrayAdaper将names的内容填充进去
    13         //方法:public ArrayAdapter (Context context, int resource, int textViewResourceId),第二个参数为布局
    14         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, names);
    15         // adpter和ListView进行绑定
    16         setListAdapter(adapter);
    17         
    18         //注:通过getListView()可以取出这个ListView
    19     }
    20 }

    运行后,也能显示出一个ListView。

    (2)事件处理

    事件处理的方法为:onListItemClick();

    ListActiviy这个类中已经包含了事件处理的监听器,所以我们只需要复写其中的onListItemClick()即可:

    1     //重写ListActivity中的onListItemClick方法来实现列表项的单击事件
    2     @Override
    3     protected void onListItemClick(ListView l, View v, int position, long id) {
    4         // TODO Auto-generated method stub
    5         super.onListItemClick(l, v, position, id);
    6     }

    (3)ListActivity的布局默认是由一个单一的在屏幕中心的全屏幕的列表,用setcontentview()在在oncreate()设置您自己的自定义屏幕布局视图布局,必须包含一个列表视图的对象ID:"@android:id/list“

    (4)自定义视图可以包含任何类型,显示另一个视图对象列表视图是空的,必须包含一个视图对象的ID:android:id/empty。

    三、单选和多选模式:

    单选模式:

    1         String[] cities = { "北京", "成都", "重庆", "武汉" };
    2         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    3                 android.R.layout.simple_list_item_single_choice, cities);
    4         listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

    多选模式:

    1         String[] cities = { "北京", "成都", "重庆", "武汉" };
    2         ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    3                 android.R.layout.simple_list_item_multiple_choice, cities);
    4         listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

    五、ListView实现图文列表:

    1、使用SimpleAdapter建立复杂的列表项:

    使用到的方法是:

    android.widget.SimpleAdapter.SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
    • 第2个参数data:每个Item就是一个Map,多个Map放在一个List当中。这个List是一个集合对象。,每一个map中应该包含所有在from参数中指定的键;(例如,data里放入图片和文字)
    • 第3个参数resource:一个自定义列表项的布局文件的资源ID。布局文件将至少应包含在to中定义了的ID。(通俗来说,就是先定义一个Item的模板)
    • 第4个参数from:一个将被添加到Map映射上的键名
    • 第5个参数to:将绑定数据的视图的ID,跟from参数对应,这些应该全是TextView。

    举例说明,完整版代码如下:

    布局文件activity3.xml的代码:

    <?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/listView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >
        </ListView>
    </LinearLayout>

    下面新建一个布局文件activity_main_item.xml,作为一个Item的模板:

    <?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="wrap_content"
        android:orientation="horizontal"
        android:gravity="center" >
        <ImageView
            android:id="@+id/imageView1"
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:src="@drawable/vae" />
        <TextView
            android:id="@+id/textView1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="20sp" />
    </LinearLayout>

    这个布局文件展示的效果如下:

    495033ba-d71d-40ba-a783-0d6cac53fdde

    然后,MainActivity.java的代码如下:

     1 import java.util.ArrayList;
     2 import java.util.HashMap;
     3 import java.util.List;
     4 import java.util.Map;
     5 import android.app.Activity;
     6 import android.os.Bundle;
     7 import android.view.Menu;
     8 import android.widget.ListView;
     9 import android.widget.SimpleAdapter;
    10 public class MainActivity extends Activity {
    11     private ListView listView;
    12     @Override
    13     protected void onCreate(Bundle savedInstanceState) {
    14         super.onCreate(savedInstanceState);
    15         setContentView(R.layout.activity_main);
    16         listView = (ListView) findViewById(R.id.listView1);
    17         //步骤1 一个列表项的内容,就是一个item
    18         Map<String, Object> item1 = new HashMap<String, Object>();
    19         item1.put("image", R.drawable.vae);
    20         item1.put("name", "许嵩");
    21         //步骤1:一个列表项的内容,就是一个item,即一个Map
    22         Map<String, Object> item2 = new HashMap<String, Object>();
    23         item2.put("image", R.drawable.smyh);
    24         item2.put("name", "生命壹号");
    25         
    26         //步骤2:把这些Map放到List当中
    27         List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
    28         data.add(item1);
    29         data.add(item2);
    30         
    31         //注意:第四个参数和第五个参数要一一对应
    32         SimpleAdapter simpleAdapter = new SimpleAdapter(this, data,
    33                 R.layout.activity_main_item, new String[] { "image", "name" },
    34                 new int[] { R.id.imageView1, R.id.textView1 });
    35         
    36         //步骤3:将List中的内容填充到listView里面去
    37         listView.setAdapter(simpleAdapter);
    38     }
    39     @Override
    40     public boolean onCreateOptionsMenu(Menu menu) {
    41         // Inflate the menu; this adds items to the action bar if it is present.
    42         getMenuInflater().inflate(R.menu.main, menu);
    43         return true;
    44     }
    45 }

    运行后,效果如下:

    【工程文件】

    链接:http://pan.baidu.com/s/1pJLmvJt

    密码:q63j

    如果item比较多的话,可以用for循环来做

    2、自定义适配器BaseAdapter实现更灵活的列表:【重要】

    之前使用SimpleAdapter,它的局限性在于,SimpleAdapter已经将内部的结构(即每个item)封装好了,然后按照这种格式叠加起来,无法进行额外的处理。所以,这时候可以使用BaseAdapter实现更灵活的列表。

    (1)方法:实际上,就是自己写一个MyAdapter类,让它继承BaseAdapter。需要复写该类的四个方法:

    • public int getCount() :通过 adapter告诉 最要在 listView(view) 中显示 多少条目 的数据。
    • public Object getItem(int position)
    • public long getItemId(int position)
    • public View getView(int position, View convertView, ViewGroup parent):用来 显示 【每个条目时】 会被调用到的 方法。

    最重要的是 getCount() 和 getView()。

    (2)ListView 的优化:

    • 重复使用convertView
    • 使用ViewHolder提高在容器中查找组件的效率

    完整版代码如下:

    activity_main.xml:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:layout_width="match_parent"
     4     android:layout_height="match_parent"
     5     android:paddingBottom="@dimen/activity_vertical_margin"
     6     android:paddingLeft="@dimen/activity_horizontal_margin"
     7     android:paddingRight="@dimen/activity_horizontal_margin"
     8     android:paddingTop="@dimen/activity_vertical_margin"
     9     tools:context=".MainActivity" >
    10     <ListView
    11         android:id="@+id/listView1"
    12         android:layout_width="match_parent"
    13         android:layout_height="match_parent" >
    14     </ListView>
    15 </LinearLayout>

    注:为了优化,第13行的代码一定要写match_parent,而不是wrap_content,解释略。

    activity_main_item.xml:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3     android:layout_width="match_parent"
     4     android:layout_height="wrap_content"
     5     android:orientation="horizontal"
     6     android:gravity="center" >
     7     
     8     <ImageView
     9         android:id="@+id/imageView1"
    10         android:layout_width="81dp"
    11         android:layout_height="81dp"
    12         android:src="@drawable/vae" />
    13     <TextView
    14         android:id="@+id/textView1"
    15         android:layout_width="match_parent"
    16         android:layout_height="wrap_content"
    17         android:text="TextView" />    
    18 </LinearLayout>

    Mainactivity.java:

     1 package com.smyhvae.smyh005listview4;
     2 import android.app.Activity;
     3 import android.os.Bundle;
     4 import android.view.Menu;
     5 import android.view.View;
     6 import android.view.ViewGroup;
     7 import android.widget.BaseAdapter;
     8 import android.widget.ImageView;
     9 import android.widget.ListView;
    10 import android.widget.TextView;
    11 public class MainActivity extends Activity {
    12     private ListView listView;
    13     @Override
    14     protected void onCreate(Bundle savedInstanceState) {
    15         super.onCreate(savedInstanceState);
    16         setContentView(R.layout.activity_main);
    17         listView = (ListView) findViewById(R.id.listView1);
    18         listView.setAdapter(new MyAdapter());
    19     }
    20     // 定义的数据
    21     private int[] images = { R.drawable.vae, R.drawable.vae, R.drawable.vae,
    22             R.drawable.vae, R.drawable.vae, R.drawable.vae, R.drawable.vae,
    23             R.drawable.vae, R.drawable.vae, R.drawable.vae, R.drawable.vae,
    24             R.drawable.vae };
    25     private String[] names = { "生命01号", "生命02号", "生命03号", "生命04号", "生命05号",
    26             "生命06号", "生命07号", "生命08号", "生命09号", "生命10号", "生命11号", "生命12号" };
    27     
    28     //自定义适配器
    29     class MyAdapter extends BaseAdapter{
    30         @Override
    31         public int getCount() {
    32             // TODO Auto-generated method stub
    33             return names.length;
    34         }
    35         @Override
    36         public Object getItem(int position) {
    37             // TODO Auto-generated method stub
    38             return names[position];
    39         }
    40         @Override
    41         public long getItemId(int position) {
    42             // TODO Auto-generated method stub
    43             return position;
    44         }
    45         @Override
    46         public View getView(int position, View convertView, ViewGroup parent) {
    47             // TODO Auto-generated method stub
    48 //            System.out.println("position=" + position);
    49 //            System.out.println(convertView);
    50 //            System.out.println("------------------------");
    51             ViewHolder vh = new ViewHolder();
    52             //通过下面的条件判断语句,来循环利用。如果convertView = null ,表示屏幕上没有可以被重复利用的对象。
    53             if(convertView==null){
    54                 //创建View
    55                 convertView = getLayoutInflater().inflate(R.layout.activity_main_item, null);
    56                 vh.iv = (ImageView) convertView.findViewById(R.id.imageView1);
    57                 vh.tv = (TextView) convertView.findViewById(R.id.textView1);
    58                 convertView.setTag(vh);
    59             }else{
    60                  vh = (ViewHolder)convertView.getTag();
    61             }
    62             vh.iv.setImageResource(images[position]);
    63             vh.tv.setText(names[position]);
    64             return convertView;
    65         }
    66         
    67     }
    68     
    69     static class ViewHolder{
    70         ImageView iv;
    71         TextView tv;
    72     }
    73     @Override
    74     public boolean onCreateOptionsMenu(Menu menu) {
    75         // Inflate the menu; this adds items to the action bar if it is present.
    76         getMenuInflater().inflate(R.menu.main, menu);
    77         return true;
    78     }
    79 }

    运行效果如下:

    【工程文件】

    链接:http://pan.baidu.com/s/1hqvImfM

    密码:oytm

    五、ListView刷新分页

    这个过程说来话长,具体参考本人另外一篇博客:

    Android UI组件----自定义ListView实现动态刷新

     

    我的公众号

    想学习代码之外的软技能?不妨关注我的微信公众号:生命团队(id:vitateam)。

    扫一扫,你将发现另一个全新的世界,而这将是一场美丽的意外:

  • 相关阅读:
    Commons.net FTPClient 上传文件
    C盘空间不够,清除VS下的 Font Cache
    Redis 密码设置
    Window bat expdp 定时任务逻辑备份 定时删除N天前的旧文件
    Windows下修改Oracle默认的端口1521
    Intellij idea 乱码问题(英文操作系统)
    给VMware下的Linux扩展磁盘空间(以CentOS6.3为例)转
    TortoiseSVN and TortoiseGit 版本控制图标不见了
    R语言中字符串的拼接操作
    SparkR:数据科学家的新利器
  • 原文地址:https://www.cnblogs.com/qianguyihao/p/3910884.html
Copyright © 2020-2023  润新知