zoukankan      html  css  js  c++  java
  • 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)。

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

  • 相关阅读:
    CNN comprehension
    Gradient Descent
    Various Optimization Algorithms For Training Neural Network
    gerrit workflow
    jenkins job配置脚本化
    Jenkins pipeline jobs隐式传参
    make words counter for image with the help of paddlehub model
    make words counter for image with the help of paddlehub model
    git push and gerrit code review
    image similarity
  • 原文地址:https://www.cnblogs.com/qianguyihao/p/3910884.html
Copyright © 2011-2022 走看看