1.ListView的样子
打开任意一款Android手机的“设置”选项,你所看到的效果就是ListView的效果。类似下图:
2.详细剖析ListView
ListView界面的每一行就是ListView的一个“条目”。
我们是需要对list的条目设置界面的。也就是说List的条目的界面是由我们程序员去设计的。你想显示什么内容,就设计什么界面。
怎样设置每一个条目呢?
例如:
姓名 电话 存款
老张 123 888
老李 145 999
我们把每一个条目设置在在item.xml中:
item.xml:
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
android:layout_width="120dp"
android:layout_height="50dp"
android:textSize="22sp"
android:id="@+id/name"/>
android:layout_width="150dp"
android:layout_height="50dp"
android:textSize="22sp"
android:id="@+id/phone"/>
android:layout_width="fill_parent"
android:layout_height="50dp"
android:textSize="22sp"
android:id="@+id/amount"/>
接下来为应用引入ListView显示控件:
main.xml:
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="50dp"
android:orientation="horizontal" >
android:layout_width="120dp"
android:layout_height="wrap_content"
android:textSize="22sp"
android:text="@string/name"/>
android:layout_width="150dp"
android:layout_height="wrap_content"
android:textSize="22sp"
android:text="@string/phone"/>
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="22sp"
android:text="@string/money"/>
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/listview"/>
引入后,我们就要把数据显示在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 Listpersons=new ArrayList ();
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 ListgetPersons(){
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() {
//得到数据数组
Listpersons=persondb.getPersons();
//SimpleAdapter需要填入Map的数据,所以要将Person转化为Map形式
List> data=new ArrayList >();
for(Person person:persons){
HashMapitem=new HashMap ();
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* 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 Listpersons;//要绑定的数据
private int resource;//绑定的条目界面
private LayoutInflater inflater;
//LayoutInflater是布局填充器(Android系统内置的一项服务),
//用一个Xml文件来生成一个view对象
public PersonAdapter(){
}
public PersonAdapter(Context context,Listpersons,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() {
//得到数据数组
Listpersons=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 Listpersons;//要绑定的数据
private int resource;//绑定的条目界面
private LayoutInflater inflater;
//LayoutInflater是布局填充器(Android系统内置的一项服务),
//用一个Xml文件来生成一个view对象
public PersonAdapter(){
}
public PersonAdapter(Context context,Listpersons,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://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net