三种实现方法,由浅入深。这中间要注意Adapter的用法,其实你要是看过Android的文档,你会发现有很多Adapter,
如果你还不太清楚适配器模式,可以先补补这方面的知识。在实际工作中,设计模式是个很好的帮手。
两个layout文件:
main.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="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
></ListView>
</LinearLayout>
listview.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/linerlayout1"
android:orientation="vertical"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
>
<TextView
android:id="@+id/person_name"
android:textSize="23sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/person_age"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/person_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/person_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
Activity:LincListViewActivity.java
package com.linc.listview;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class LincListViewActivity extends Activity {
private final static String[] data = {"张飞","张辽","张角","张三丰","张牙舞爪","张灯结彩","张唑啉","张大民"};
//创建数据源.
Zhang[] data2 = new Zhang[]{
new Zhang("张飞",38,"zhangfei@gmail.com","燕山"),
new Zhang("张辽",36,"zhangliao@sina.com","雁门"),
new Zhang("张角",51,"zhangjiao@gmail.com","钜鹿"),
new Zhang("张三丰",200,"sanfeng@gmail.com","辽东"),
new Zhang("张牙舞爪",25,"5zhao@gmail.com","冀州"),
new Zhang("张灯结彩",25,"5zhao@gmail.com","冀州") ,
new Zhang("张唑啉",25,"5zhao@gmail.com","冀州") ,
new Zhang("张大民",25,"5zhao@gmail.com","冀州") ,
new Zhang("张牙舞爪",25,"5zhao@gmail.com","冀州")
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listview = (ListView)findViewById(R.id.listview);
/*
* 第一种:普通字符串
*/
ArrayAdapter<String> adapter1 = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,data);
/*
* 第二种:文艺类对象
*/
ArrayAdapter<Zhang> adapter2 = new ArrayAdapter<Zhang>(this,
android.R.layout.simple_list_item_1,data2);
/*
* 第三种:自定义适配器
*/
ListAdapter adapter3 = new ListAdapter(this, R.layout.listview,data2) ;//okay, the resource id is passed.
listview.setAdapter(adapter3);
}
}
数据类对象:Zhang.java
package com.linc.listview;
public class Zhang {
private String name;
private int age;
private String email;
private String address;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getEmail() {
return email;
}
public String getAddress() {
return address;
}
public Zhang(String name, int age, String email, String address) {
super();
this.name = name;
this.age = age;
this.email = email;
this.address = address;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", email=" + email
+ ", address=" + address + "]";
}
}
适配器类:ListAdapter.java
package com.linc.listview;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
public class ListAdapter extends ArrayAdapter<Zhang> {
private LayoutInflater mInflater;
public ListAdapter(Context context, int textViewResourceId,Zhang[] obj) {
super(context, textViewResourceId,obj);
// TODO Auto-generated constructor stub
this.mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
//创建新的view视图.
convertView = mInflater.inflate(R.layout.listview, null); //see above, you can use the passed resource id.
}
ViewHolder holder = null;
if(holder==null){
holder = new ViewHolder();
//查找每个ViewItem中,各个子View,放进holder中
holder.name = (TextView) convertView.findViewById(R.id.person_name);
holder.age = (TextView) convertView.findViewById(R.id.person_age);
holder.email = (TextView) convertView.findViewById(R.id.person_email);
holder.address = (TextView) convertView.findViewById(R.id.person_address);
//保存对每个显示的ViewItem中, 各个子View的引用对象
convertView.setTag(holder);
}
else// I think this a bug, program can not run here!!!--linc2014.11.12
{
holder = (ViewHolder)convertView.getTag();
}
//获取当前要显示的数据
Zhang person = getItem(position);
holder.name.setText(person.getName());
holder.age.setText(String.valueOf(person.getAge()));
holder.email.setText(person.getEmail());
holder.address.setText(person.getAddress());
return convertView;
}
private static class ViewHolder
{
TextView name;
TextView age;
TextView email;
TextView address;
}
}
更复杂的一个例子: 单行与多行并存
还可以参考:View Tag的介绍
或者对比着GridView来学习一下它们的异同,Android自定义GridView之实现一个图片加多个文本框
它们的Adapter一个是继承自ArrayAdapter,另一个是BaseAdapter。
另外,API demo中相关的例子一定要看看。那才是真正的宝藏呢。
下面直接给出List14源码:
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.view;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import android.widget.ImageView;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import com.example.android.apis.R;
/**
* Demonstrates how to write an efficient list adapter. The adapter used in this example binds
* to an ImageView and to a TextView for each row in the list.
*
* To work efficiently the adapter implemented here uses two techniques:
* - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary
* - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary
*
* The ViewHolder pattern consists in storing a data structure in the tag of the view returned by
* getView(). This data structures contains references to the views we want to bind data to, thus
* avoiding calls to findViewById() every time getView() is invoked.
*/
public class List14 extends ListActivity {
private static class EfficientAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private Bitmap mIcon1;
private Bitmap mIcon2;
public EfficientAdapter(Context context) {
// Cache the LayoutInflate to avoid asking for a new one each time.
mInflater = LayoutInflater.from(context);
// Icons bound to the rows.
mIcon1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_1);
mIcon2 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon48x48_2);
}
/**
* The number of items in the list is determined by the number of speeches
* in our array.
*
* @see android.widget.ListAdapter#getCount()
*/
public int getCount() {
return DATA.length;
}
/**
* Since the data comes from an array, just returning the index is
* sufficent to get at the data. If we were using a more complex data
* structure, we would return whatever object represents one row in the
* list.
*
* @see android.widget.ListAdapter#getItem(int)
*/
public Object getItem(int position) {
return position;
}
/**
* Use the array index as a unique id.
*
* @see android.widget.ListAdapter#getItemId(int)
*/
public long getItemId(int position) {
return position;
}
/**
* Make a view to hold each row.
*
* @see android.widget.ListAdapter#getView(int, android.view.View,
* android.view.ViewGroup)
*/
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unneccessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// Bind the data efficiently with the holder.
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);
return convertView;
}
static class ViewHolder {
TextView text;
ImageView icon;
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new EfficientAdapter(this));
}
private static final String[] DATA = Cheeses.sCheeseStrings;
}