今天我们讲的也是非常重要的一个控件listview—最常用也是最难的

一个ListView通常有两个职责

(1)将数据填充到布局。

(2)处理用户的选择点击等操作。

  第一点很好理解,ListView就是实现这个功能的。第二点也不难做到,在后面的学习中读者会发现,这非常简单。

一个ListView的创建需要3个元素

(1)ListView中的每一列的View。

(2)填入View的数据或者图片等。

(3)连接数据与ListView的适配器。

也就是说,要使用ListView,首先要了解什么是适配器。适配器是一个连接数据和AdapterView(ListView就是一个典型的AdapterView,后面还会学习其他的)的桥梁,通过它能有效地实现数据与AdapterView的分离设置,使AdapterView与数据的绑定更加简便,修改更加方便

Android中提供了很多的Adapter,表4-5列出了常用的几个。

表4-5 常用适配器

Adapter

含义

ArrayAdapter<T>

用来绑定一个数组,支持泛型操作

SimpleAdapter

用来绑定在xml中定义的控件对应的数据

SimpleCursorAdapter

用来绑定游标得到的数据

BaseAdapter

通用的基础适配器

其实适配器还有很多,要注意的是,各种Adapter只不过是转换的方式和能力不一样而已。

ListView使用SimpleAdapter

很多时候需要在列表中展示一些除了文字以外的东西,比如图片等。这时候可以使用SimpleAdapter。SimpleAdapter的使用也非常简单,同时它的功能也非常强大。可以通过它自定义ListView中的item的内容,比如图片、多选框等。

使用simpleAdapter的数据一般都是用HashMap构成的列表,列表的每一节对应ListView的每一行。通过SimpleAdapter的构造函数,将HashMap的每个键的数据映射到布局文件中对应控件上。这个布局文件一般根据自己的需要来自己定义。梳理一下使用SimpleAdapter的步骤。

(1)根据需要定义ListView每行所实现的布局。

(2)定义一个HashMap构成的列表,将数据以键值对的方式存放在里面。

(3)构造SimpleAdapter对象。

(4)将LsitView绑定到SimpleAdapter上。

BaseAdapter

  在ListView的使用中,有时候还需要在里面加入按钮等控件,实现单独的操作。也就是说,这个ListView不再只是展示数据,也不仅仅是这一行要来处理用户的操作,而是里面的控件要获得用户的焦点。读者可以试试用SimpleAdapter添加一个按钮到ListView的条目中,会发现可以添加,但是却无法获得焦点,点击操作被ListView的Item所覆盖。这时候最方便的方法就是使用灵活的适配器BaseAdapter了。

  当系统开始绘制ListView的时候,首先调用getCount()方法。得到它的返回值,即ListView的长度。然后系统调用getView()方法,根据这个长度逐一绘制ListView的每一行。也就是说,如果让getCount()返回1,那么只显示一行。而getItem()和getItemId()则在需要处理和取得Adapter中的数据时调用。那么getView如何使用呢?如果有10000行数据,就绘制10000次?这肯定会极大的消耗资源,导致ListView滑动非常的慢,那应该怎么做呢?

下面就通过微信的例子说明吧!

下面是布局文件

 <?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="match_parent" >
</ListView> </LinearLayout>

listview_layout.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="wrap_content"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_horizontal_margin"
android:paddingBottom="@dimen/activity_horizontal_margin"
android:orientation="horizontal" > <ImageView
android:id="@+id/face"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/houzi" /> <LinearLayout
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical" > <LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="3dp"
android:orientation="horizontal" > <TextView
android:layout_weight="1"
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textColor="#7F7F7F"/> <TextView
android:id="@+id/date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#A9A9A9"/>
</LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="3dp"
android:orientation="horizontal" >
<TextView
android:layout_weight="1"
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:textColor="#A9A9A9"/>
<TextView
android:id="@+id/noRead"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:text=""
android:textColor="#FF0000"/>
</LinearLayout>
</LinearLayout> </LinearLayout>

middle2.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.main.weixin.MainActivity" > <!-- 头部 -->
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
> <include layout="@layout/head"/> </LinearLayout> <!-- 中间 -->
<LinearLayout
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="match_parent"> <include layout = "@layout/listview_layout"></include> </LinearLayout> <!-- 尾部 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
> <include layout="@layout/bottom"/> </LinearLayout>
</LinearLayout>

activity_main.xml

下面是activity主要文件

 package com.weixin.entity;

 public class Messages {

     private String face;
private String name;
private String Date;
private String content;
private Integer noRead; public String getFace() {
return face;
}
public void setFace(String face) {
this.face = face;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDate() {
return Date;
}
public void setDate(String date) {
Date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Integer getNoRead() {
return noRead;
}
public void setNoRead(Integer noRead) {
this.noRead = noRead;
} }

Message

 package com.main.weixin;

 import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import com.database.weixin.MyDatabaseOpenHelper;
import com.weixin.entity.Messages; import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView; public class MainActivity extends Activity { private SimpleAdapter sa;
private BaseAdapter ba;
private ListView lv;
private List<Messages> listMessage = new ArrayList<Messages>();
private List<Map<String,Object>> listMessage2 = new ArrayList<Map<String,Object>>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main); //模拟读取数据库或者互联网
for(int i=0 ; i<100 ; i++){
Messages message = new Messages();
message.setFace("houzi");
message.setName("孙行者"+i);
message.setDate("昨天");
message.setContent("有空吗?今晚一起吃饭");
message.setNoRead(i);
listMessage.add(message);//方法一 /* //定义一个界面与数据混合体,一个Item代表一行记录
Map<String,Object> item = new HashMap<String,Object>();
//一行多个空件
item.put("face", R.drawable.houzi);
item.put("name", "孙行者"+i);
item.put("date", "昨天");
item.put("content", "有空吗?今晚一起吃饭");
listMessage2.add(item);*/ } lv = (ListView) findViewById(R.id.listView1); /* sa = new SimpleAdapter(this,
listMessage2, //data 不仅是数据,而是数据与界面高耦合的混合体
R.layout.middle1,
new String[]{"face","name","date","content"},
new int[]{R.id.face,R.id.name,R.id.date,R.id.content}); lv.setAdapter(sa); //添加事件
lv.setOnItemClickListener(new OnItemClickListener(){ @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) { Map<String,Object> item =listMessage2.get(position);
item.put("name", "行者孙"+position);
sa.notifyDataSetChanged();
} }); */ //简单理解为VC绑在一起
ba = new BaseAdapter(){ //返回记录数目
@Override
public int getCount() { return listMessage.size(); } //每一个item项,返回一次界面
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view ; //布局不变,数据变 //如果缓存为空,我们生成新的布局作为1个item
if(convertView == null){
Log.i("info:", "没有缓存,重新生成"+position);
LayoutInflater inflater = MainActivity.this.getLayoutInflater(); //因为getView()返回的对象,adapter会自动赋给ListView
view = inflater.inflate(R.layout.middle2, null); }else{
Log.i("info:", "有缓存,不需要重新生成"+position);
view = convertView; } Messages m = listMessage.get(position);
Integer noRead = m.getNoRead(); TextView tv_name = (TextView) view.findViewById(R.id.name);
tv_name.setText(m.getName()); TextView tv_date = (TextView) view.findViewById(R.id.date);
tv_date.setText(m.getDate()); TextView tv_content = (TextView) view.findViewById(R.id.content);
tv_content.setText(m.getContent()); System.out.println(noRead); if( noRead !=0){
TextView tv_noRead = (TextView) view.findViewById(R.id.noRead);
//这里的setText()方法接收的是一个字符串类型,而你给了一个Integer类型给它,所以报错了,这里需要把Integer类型转为String类型即可
tv_noRead.setText(noRead.toString()); } return view ; } @Override
public Object getItem(int position) {
return null;
} @Override
public long getItemId(int position) {
return 0;
} };
lv.setAdapter(ba); //添加事件
lv.setOnItemClickListener(new OnItemClickListener(){ @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Messages message = listMessage.get(position);
if(message.getNoRead()!=0){ message.setName("行者孙"+position);
message.setNoRead(0); view.findViewById(R.id.noRead).setVisibility(View.INVISIBLE); }else{
message.setName("孙行者"+position);
} ba.notifyDataSetChanged();//
} });
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

效果如下:

convertView相当于一个缓存,开始为0,当有条目变为不可见,它缓存了它的数据,后面再出来的条目只需要更新数据就可以了,这样大大节省了系统资料的开销。

Android之listview && adapter的更多相关文章

  1. Android 中 ListView Adapter getView 被多次调用问题 解决方法

    执行多次原因是因为每显示一个VIew,它都去测量view的高度,执行measure方法,导致getView执行多次. 解决方法是将 ListView 的 layout_width 设置为 fill_p ...

  2. android代码优化----ListView中自定义adapter的封装(ListView的模板写法)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  3. Android Listview & Adapter

    Listview主要有两个职责: 将数据填充到布局 处理用户的选择点击等操作 列表的显示需要三个元素: ListVeiw 用来展示列表的View 适配器(Adapter) 用来把数据映射到ListVi ...

  4. Android开发10.1:UI组件适配器AdapterView(创建ListView,Adapter接口)

    @version:Android4.3 API18 @author:liuxinming 概述               AdapterView继承了ViewGroup,它的本质是容器       ...

  5. Android ListView Adapter的getItemViewType和getViewTypeCount多种布局

     <Android ListView Adapter的getItemViewType和getViewTypeCount多种布局> 在Android的ListView中.假设在一个Lis ...

  6. Android开发笔记(12)——ListView & Adapter

    转载请注明:http://www.cnblogs.com/igoslly/p/6947225.html 下一章是关于ListFragment的内容,首先先介绍ListView的相关配置,理解ListF ...

  7. 【转】Android之自定义Adapter的ListView

    http://www.cnblogs.com/topcoderliu/archive/2011/05/07/2039862.html 在开发中,我们经常使用到ListView这个控件.Android的 ...

  8. Android之自定义Adapter的ListView

    ListView的创建,一般要具备两大元素: 1)数据集,即要映射的字符串.图片信息之类. 2)适配器,实现把要映射的字符串.图片信息映射成视图(如Textview.Image等组件),再添加到Lis ...

  9. Android—万能ListView适配器

    ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义. 最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家. 首先有一个自定义的 ...

随机推荐

  1. System.Threading.Timer 定时器的用法

    System.Threading.Timer 是C# 中的一个定时器,可以定时(不断循环)执行一个任务.它是在线程上执行的,具有很好的安全性.为此  .Net Framework 提供了5个重载的构造 ...

  2. java反射,ReflectUtils

    public class ReflectUtils { /** * 通过构造函数实例化对象 * @param className 类的全路径名称 * @param parameterTypes 参数类 ...

  3. PHP数据类型

    在PHP中,一共支持8种数据类型:整型,浮点型,布尔型,字符串型,数组,对象,空类型(NULL),资源型 标量类型 int(integet)整数类型 整型数据:在内存中占4个字节,也就是32个bit位 ...

  4. 1 《JavaScript高级程序设计》学习笔记(1)

    欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 首先,我将从<JavaScript高级程序设计>这本JavaScript学习者必看的经典教 ...

  5. 进击的docker 一 : Docker 简介

    Docker简介 1.什么是docker 1.1.docker 起源 开源项目 诞生2013年初 GO语言开发实现 遵从了Apache2.0协议 项目代码在GitHub维护 1.2.docker目标 ...

  6. 64位 SQL Server2008链接访问Oracle 过程汇总解决方法记录

    64位 SQL Server2008链接访问Oracle 过程汇总解决方法记录 经过几天不停的网上找资料,实验,终于联通了. 环境:系统:win 2008 ,SqlServer2008 R2, 连接O ...

  7. ajax通讯之格式详解

    前言: ajax的出现,一定程度上改变了js的命运,同时也被广泛使用,而jq的兴起也大大降低了ajax的使用难度.虽然,jq的ajax方法使用起来十分便利,但是大部分开发人员也仅仅只是对其中的几个属性 ...

  8. Servlet--表单、超链接、转发、重定向4种情况的路径

    Servlet中相对路径总结 假设web工程使用如下目录结构: 在介绍相对路径和绝对路径前需要先了解几个概念: 服务器的站点根目录:以tomcat服务器为例,tomcat服务器站点根目录就是apach ...

  9. Linux常用性能调优工具索引

    root@ubuntu:~# dstat----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--usr sys i ...

  10. 查看python api

    以下方法可以查看python 的api,包括selenium webdriver,requests等 1.cmd进入dos命令行窗口,输入python -m pydoc -p 2345   (2345 ...