【Android开发】基本组件-ListView(重要)

来源:互联网 发布:武汉seo大牛 编辑:程序博客网 时间:2024/04/29 10:31

1.ListView的样子

打开任意一款Android手机的“设置”选项,你所看到的效果就是ListView的效果。类似下图:


2.详细剖析ListView

ListView界面的每一行就是ListView的一个“条目”。
我们是需要对list的条目设置界面的。也就是说List的条目的界面是由我们程序员去设计的。你想显示什么内容,就设计什么界面。

怎样设置每一个条目呢?
例如:
姓名    电话     存款
老张    123      888
老李    145      999

我们把每一个条目设置在在item.xml中:
item.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="horizontal" >        <TextView      android:layout_width="120dp"     android:layout_height="50dp"     android:textSize="22sp"     android:id="@+id/name"/>        <TextView      android:layout_width="150dp"     android:layout_height="50dp"     android:textSize="22sp"     android:id="@+id/phone"/>        <TextView      android:layout_width="fill_parent"     android:layout_height="50dp"     android:textSize="22sp"     android:id="@+id/amount"/></LinearLayout>

接下来为应用引入ListView显示控件:
main.xml:
<pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >        <!--name、phone、money是表头-->    <LinearLayout    android:layout_width="fill_parent"    android:layout_height="50dp"    android:orientation="horizontal" >       <TextView     android:layout_width="120dp"    android:layout_height="wrap_content"    android:textSize="22sp"    android:text="@string/name"/>      <TextView     android:layout_width="150dp"    android:layout_height="wrap_content"    android:textSize="22sp"    android:text="@string/phone"/>      <TextView     android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:textSize="22sp"    android:text="@string/money"/>    </LinearLayout>    <!--引入ListView控件-->    <ListView        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:id="@+id/listview"/></LinearLayout>

引入后,我们就要把数据显示在ListView上面。

数据模拟(Person类和模拟数据库的数据的PersonDB,从PersonDB中可以获取ListView列表要显示的值)Person:

package com.example.model;public class Person {      private String name;      private String phone;      private int money;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}public Person(){}public Person(String name,String p,int m){this.name=name;this.phone=p;this.money=m;}}

PersonDB:
package com.example.model;import java.util.ArrayList;import java.util.List;import android.database.Cursor;public class PersonDB {public List<Person> persons=new ArrayList<Person>();Person p1=new Person("老张","13563325622",20000);Person p2=new Person("老李","17663325622",4230);Person p3=new Person("老赵","18863325622",223400);Person p4=new Person("老刘","15563325622",2340);Person p5=new Person("老纪","15467825622",34600);Person p6=new Person("老朱","12389525622",55670);Person p7=new Person("老徐","13459225622",2234200);Person p8=new Person("老王","14350225622",2340000);Person p9=new Person("老许","13458025622",123000);public List<Person> getPersons(){persons.add(p1);persons.add(p2);persons.add(p3);persons.add(p4);persons.add(p5);persons.add(p6);persons.add(p7);persons.add(p8);persons.add(p9);return persons;}}

打开Activity,当窗口打开的时候就要显示数据,所以在onCreat()方法中就要完成数据的显示。

这里用的适配器是SimpleAdapter

package com.example.listview;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;import android.widget.SimpleAdapter;import com.example.model.Person;import com.example.model.PersonDB;public class MainActivity extends Activity {    private ListView listView;    private PersonDB persondb=new PersonDB();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);listView=(ListView)this.findViewById(R.id.listview);show();}private void show() {//得到数据数组List<Person> persons=persondb.getPersons();//SimpleAdapter需要填入Map的数据,所以要将Person转化为Map形式List<HashMap<String,Object>> data=new ArrayList<HashMap<String,Object>>();for(Person person:persons){ HashMap<String,Object> item=new HashMap<String, Object>(); item.put("name",person.getName()); item.put("phone",person.getPhone()); item.put("money",person.getMoney()); data.add(item);}//需要把数据通过适配器绑定到条目界面的显示控件上//适配器的作用是实现数据的绑定//有几种适配器:SimpleAdapter、SimpleCursorAdapter等//我们亦可以自定义适配器//参数1上下文,参数2Map型的数据,参数3要绑定的控件名,参数4和5分别是要把哪一项数据绑定到界面的哪一个控件上SimpleAdapter adapter=new SimpleAdapter(this,data,R.layout.item,new String[]{"name","phone","money"},new int[]{R.id.name,R.id.phone,R.id.amount});    listView.setAdapter(adapter);    /*listView如何将数据显示出来呢?    *一旦把适配器设给listview之后,listview就会首先调用适配器里面的getCout(),用来得到数据    *的总数(int total=adapter.getCount())。得到总数后,可以根据每个条目的高度计算出在一个窗口    *里面应该显示多少个条目(perpage)。    *for(int i=0;i<perpage;i++){    *  View view=adapter.getView(position,convertView,parent);//用于的到条目的view对象    *  //显示条目,下一次翻滚上来的时候用的就是它的缓存了,也就不再new原来的条目了。    }*/}}

测试成功。

效果如图:

3.点击条目触发事件

给ListView控件设置点击条目的监听器即可。方法:

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);listView=(ListView)this.findViewById(R.id.listview);listView.setOnItemClickListener(new ItemClickListener());show3();}public final class ItemClickListener implements OnItemClickListener{@Override//当ListView的条目被点中之后,就会调用这个方法//参数:参数1当前被点的条目所在的LIstView,参数2是当前条目的view对象,//参数3是当前点击的条目所绑定的数据在集合中的索引值,参数4是view界面在List中的排列的Idpublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {ListView lView=(ListView)parent;//getItemAtPosition方法实际上//调用了适配器的getItem()方法//即是根据索引值取得集合中的某个元素Person person=(Person)lView.getItemAtPosition(position);Toast.makeText(getApplicationContext(), person.getName(), 1).show();}  }
数据如果不是ListView,而是其他的,写法根据情况改变。


4.自定义适配器

在上一个工程的基础上介绍自定义适配器的开发:
要继承BaseAdapter类,并重写getCount()、getItem()、getItemId()和getView()方法

PersonAdapter.java:

package com.example.adapter;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.listview.R;import com.example.model.Person;public class PersonAdapter extends BaseAdapter {   //改写getCount()、getItem(int arg0)、getItemId(int arg0)和getView方法private List<Person> persons;//要绑定的数据private int resource;//绑定的条目界面private LayoutInflater inflater;//LayoutInflater是布局填充器(Android系统内置的一项服务),//用一个Xml文件来生成一个view对象public PersonAdapter(){}public PersonAdapter(Context context,List<Person> persons,int resource) {this.persons=persons;this.resource=resource;//得到布局填充服务inflater=(LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);}@Override//得到要绑定的数据的记录总数public int getCount() {return persons.size();}@Override//外面给定一个索引值,就可以从这个集合中得到该索引对应的条目public Object getItem(int position) {return persons.get(position);}@Override//取得条目的Idpublic long getItemId(int position) {return position;}@Override//取得代表条目的view对象//要实现数据绑定public View getView(int position, View convertView, ViewGroup parent) {// 重用第一页已经new好的对象if(convertView==null){//缓存为null,是第一页//如果不是第一页,这里没有进行优化,详情见下面优化后的程序//为条目创建view对象convertView=inflater.inflate(resource, null);}TextView nameView=(TextView) convertView.findViewById(R.id.name);TextView phoneView=(TextView) convertView.findViewById(R.id.phone);TextView amountView=(TextView) convertView.findViewById(R.id.amount);//该条目所要的数据在集合中的索引值positionPerson person=persons.get(position);//下面代码实现数据绑定nameView.setText(person.getName());phoneView.setText(person.getPhone());amountView.setText(person.getMoney()+"");return convertView;}}

测试:
//自定义适配器private void show3() {//得到数据数组List<Person> persons=persondb.getPersons();PersonAdapter adapter=new PersonAdapter(this,persons,R.layout.item);listView.setAdapter(adapter);}
测试成功。


优化:(让适配器运行的时候,条目向下拉再向上拉返回的时候,读取过的条目只去读缓存即可)
package com.example.adapter;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import com.example.listview.R;import com.example.model.Person;public class PersonAdapter extends BaseAdapter {   //改写getCount()、getItem(int arg0)、getItemId(int arg0)和getView方法private List<Person> persons;//要绑定的数据private int resource;//绑定的条目界面private LayoutInflater inflater;//LayoutInflater是布局填充器(Android系统内置的一项服务),//用一个Xml文件来生成一个view对象public PersonAdapter(){}public PersonAdapter(Context context,List<Person> persons,int resource) {this.persons=persons;this.resource=resource;//得到布局填充服务inflater=(LayoutInflater)context.getSystemService(context.LAYOUT_INFLATER_SERVICE);}@Override//得到要绑定的数据的记录总数public int getCount() {return persons.size();}@Override//外面给定一个索引值,就可以从这个集合中得到该索引对应的条目public Object getItem(int position) {return persons.get(position);}@Override//取得条目的Idpublic long getItemId(int position) {return position;}@Override//取得代表条目的view对象//要实现数据绑定public View getView(int position, View convertView, ViewGroup parent) {TextView nameView=null;TextView phoneView=null;TextView amountView=null;// 重用第一页已经new好的对象if(convertView==null){//缓存为null,是第一页//如果不是第一页,listview会把之前缓存过的view对象传进来//为条目创建view对象convertView=inflater.inflate(resource, null);nameView=(TextView) convertView.findViewById(R.id.name);phoneView=(TextView) convertView.findViewById(R.id.phone);amountView=(TextView) convertView.findViewById(R.id.amount);ViewCache cache=new ViewCache();cache.nameView=nameView;cache.phoneView=phoneView;cache.amountView=amountView;convertView.setTag(cache);//视图有个标志,把它用作临时存放缓存数据}else{//如果不是第一页,listview会把之前缓存过的view对象传进来   ViewCache cache=(ViewCache)convertView.getTag();   nameView=cache.nameView;   phoneView=cache.phoneView;   amountView=cache.amountView;}//该条目所要的数据在集合中的索引值positionPerson person=persons.get(position);//下面代码实现数据绑定nameView.setText(person.getName());phoneView.setText(person.getPhone());amountView.setText(person.getMoney()+"");return convertView;}//代码优化://用来对view进行缓存的内部类private final class ViewCache{public TextView nameView;public TextView phoneView;public TextView amountView;}}
转载请注明出处:http://blog.csdn.net/acmman/article/details/44833565

0 0