一、继承listActivity、使用arrayAdapter
使用ListView和arrayAdapter布局,是ListView布局中最为简单的一种,首先我们会建立一个组件用来显示数据,例如main.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- 主界面本身就是一个显示组件 -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
>
</TextView>
Activity代码如下
package cn.com.android.grid;
import android.app.ListActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class listViewTest extends ListActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String data[] = getData();
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, R.layout.main, data);
this.setListAdapter(arrayAdapter);// ArrayAdapter 继承自baseAdapter,baseAdapter又继承自ListAdapter
}
private String[] getData(){
String[] data = new String[100];
for (int i = 0; i < 100; i++) {
data[i] = "列表项" + i;
}
return data;
}
}
如果这里activity不想继承ListActivity,那么我们可以这样编写
package cn.com.android.grid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class ListViewTest2 extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView listView = new ListView(this);
listView.setAdapter(new ArrayAdapter<String>(this,R.layout.main,getData()));
setContentView(listView);
}
private String[] getData(){
String[] data = new String[100];
for (int i = 0; i < 100; i++) {
data[i] = "列表项" + i;
}
return data;
}
}
废话连篇:
两种实现办法写的代码差距很大,有很多初学者可能很晕。不过不要紧,我们一起看下ListActivity到底是怎么实现的。
代码摘录如下
public class ListActivity extends Activity {
protected ListAdapter mAdapter;
protected ListView mList;
我们看到了,实际上当我们继承ListActivity时,实际上里面已经有一个从ListActivity中继承的listview了,所以千万别以为差距很大,本质上,实现的步骤是一摸一样的。你可以认为,android给你提供了一个免费的工具类。没什么稀奇的。
步骤上,还是三大步:
第一步:准备布局文件main.xml
第二步:获取数据 getData()
第三步:绑定数据源setListAdapter();
二、用simpleAdapter绑定数据
最终效果图
目录结构
main.xml主布局文件,代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<TextView
android:text="@string/name"
android:gravity="center"
android:layout_width="150px"
android:layout_height="wrap_content"
/>
<TextView
android:text="@string/age"
android:gravity="center"
android:layout_width="170px"
android:layout_height="wrap_content"
/>
</LinearLayout>
<ListView
android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>
user.xml组件布局文件代码
<?xml version="1.0" encoding="utf-8"?>
<!-- 创建存放一行数据的组件 -->
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow>
<ImageView
android:id="@+id/image"
android:layout_width="50px"
android:layout_height="50px"
></ImageView>
<TextView
android:id="@+id/userName"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="150px"
></TextView>
<TextView
android:id="@+id/userAge"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="170px"
></TextView>
</TableRow>
</TableLayout>
主Activity,listView.java代码
package cn.com.android.listView;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class listView extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listView = (ListView) findViewById(R.id.listView);
SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.user,
new String[]{"image","userName","userAge"}, new int[]{R.id.image,R.id.userName,R.id.userAge});
listView.setAdapter(adapter);
}
private ArrayList<HashMap<String, Object>> getData(){
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String,Object>>();
for(int i=0;i<10;i++){
HashMap<String, Object> tempHashMap = new HashMap<String, Object>();
tempHashMap.put("image", R.drawable.icon);
tempHashMap.put("userName", "用户"+i);
tempHashMap.put("userAge", 30-i);
arrayList.add(tempHashMap);
}
return arrayList;
}
}
strings.xml代码
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">布局列表展示</string>
<string name="app_name">列表布局</string>
<string name="name">姓名</string>
<string name="age">年龄</string>
</resources>
废话连绵:
我们一起看看结构,一个主布局文件,一个组件布局文件,一个Activity类。
依旧分为三步:
第一步:定义布局文件,设计UI,包括寻找合适的图片了等等……
第二步:获取数据。这里用的是simpleAdapter,所以要求数据必须固定格式的;
第三步:绑定数据源。
然后,我们就可以看到我们想要的结果了。
三、有按钮的ListView
下面我们是要看使用自定义的Adapter绑定数据、通过contextView.setTag绑定数据的方式,最终结果图:
代码结构示意图
vlist2.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">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5px"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="22px"
/>
<TextView
android:id="@+id/info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFFFF"
android:textSize="13px"
/>
</LinearLayout>
<Button
android:id="@+id/view_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="click me"
android:gravity="center"
/>
</LinearLayout>
listView3.java代码
package cn.com.android2.listview;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
public class listView3 extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取虚拟的数据,数据的格式有严格的要求哦
ArrayList<HashMap<String, Object>> data = getData();
//模仿SimpleAdapter实现的自己的adapter
MyAdapter adapter = new MyAdapter(this, data);
setListAdapter(adapter);
}
private ArrayList<HashMap<String, Object>> getData(){
ArrayList<HashMap<String, Object>> arrayList = new ArrayList<HashMap<String,Object>>();
for(int i=0;i<10;i++){
HashMap<String, Object> tempHashMap = new HashMap<String, Object>();
tempHashMap.put("image", R.drawable.icon);
tempHashMap.put("title", "标题"+i);
tempHashMap.put("info", "描述性信息");
arrayList.add(tempHashMap);
}
return arrayList;
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Log.i("输出信息",v.toString() );
}
}
zujian.java
package cn.com.android2.listview;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public final class ZuJian {
public ImageView imageView;
public TextView titleView;
public TextView infoView;
public Button button;
}
MyAdapter.java
package cn.com.android2.listview;
import java.util.ArrayList;
import java.util.HashMap;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
public class MyAdapter extends BaseAdapter {
private ArrayList<HashMap<String, Object>> data;
private LayoutInflater layoutInflater;
private Context context;
public MyAdapter(Context context,ArrayList<HashMap<String, Object>> data) {
this.context = context;
this.data = data;
this.layoutInflater = LayoutInflater.from(context);
}
public int getCount() {
return data.size();
}
public Object getItem(int position) {
return data.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ZuJian zuJian = null;
if(convertView==null){
zuJian = new ZuJian();
// 获取组件布局
convertView = layoutInflater.inflate(R.layout.vlist2, null);
zuJian.imageView = (ImageView) convertView.findViewById(R.id.image);
zuJian.titleView = (TextView) convertView.findViewById(R.id.title);
zuJian.infoView = (TextView) convertView.findViewById(R.id.info);
zuJian.button = (Button) convertView.findViewById(R.id.view_btn);
// 这里要注意,是使用的tag来存储数据的。
convertView.setTag(zuJian);
}
else {
zuJian = (ZuJian) convertView.getTag();
}
// 绑定数据、以及事件触发
zuJian.imageView.setBackgroundResource((Integer) data.get(position).get("image"));
zuJian.titleView.setText((String)data.get(position).get("title"));
zuJian.infoView.setText((String)data.get(position).get("info"));
zuJian.button.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
showInfo();
}
});
return convertView;
}
public void showInfo(){
new AlertDialog.Builder(context)
.setTitle("我的listview")
.setMessage("介绍...")
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.show();
}
}
废话连篇:
代码中的注释已经解释的很清楚了,这里再次强调一遍,三步骤
第一步:准备主布局文件、组件布局文件等
第二步:获取并整理数据
第三部:绑定数据,这里我们是通过自己编写adapter来完成的。
listView在开始绘制的时候,系统首先调用getCount()函数,根据他的返回值得到listView的长度,然后根据这个长度,调用getView()逐一绘制每一行。
如果你的getCount()返回值是0的话,列表将不显示同样return 1,就只显示一行。
系统显示列表时,首先实例化一个适配器(这里将实例化自定义的适配器)。当手动完成适配时,必须手动映射数据,这需要重写getView()方法。系统在绘制列表的每一行的时候将调用此方法。
getView()有三个参数,position表示将显示的是第几行,covertView是从布局文件中inflate来的布局。我们用LayoutInflater的方法将定义好的vlist2.xml文件提取成View实例用来显示。然后将xml文件中的各个组件实例化(简单的findViewById()方法)。
这样便可以将数据对应到各个组件上了。但是按钮为了响应点击事件,需要为它添加点击监听器,这样就能捕获点击事件。至此一个自定义的listView就完成了,现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了。