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

简介:

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

相关文章
|
8天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
7天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
19 5
|
5天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
6天前
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
22 3
|
9天前
|
存储 IDE 开发工具
探索Android开发之旅:从新手到专家
【10月更文挑战第26天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何在Android平台上从零开始,最终成为一名熟练的开发者。通过简单易懂的语言和实际代码示例,本文将引导你了解Android开发的基础知识、关键概念以及如何实现一个基本的应用程序。无论你是编程新手还是希望扩展你的技术栈,这篇文章都将为你提供价值和启发。让我们开始吧!
|
3天前
|
移动开发 Java Android开发
探索Android与iOS开发的差异性与互联性
【10月更文挑战第32天】在移动开发的大潮中,Android和iOS两大平台各领风骚。本文将深入浅出地探讨这两个平台的开发差异,并通过实际代码示例,展示如何在各自平台上实现相似的功能。我们将从开发环境、编程语言、用户界面设计、性能优化等多个角度进行对比分析,旨在为开发者提供跨平台开发的实用指南。
20 0
|
13天前
|
搜索推荐 Android开发 UED
安卓开发中的自定义视图:打造个性化用户界面
【10月更文挑战第22天】在安卓应用的海洋中,如何让你的应用脱颖而出?一个独特且直观的用户界面(UI)至关重要。本文将引导你通过自定义视图来打造个性化的用户体验,从基础的视图绘制到触摸事件的处理,我们将一步步深入探讨。准备好了吗?让我们开始吧!
|
1月前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
1月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
100 1