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(); @Override protected 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中的排列的Id public 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 //取得条目的Id public 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); //该条目所要的数据在集合中的索引值position Person 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 //取得条目的Id public 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; } //该条目所要的数据在集合中的索引值position Person 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