前面刚学习了arrayAdapter,但是发现arrayAdapter很有局限性,似乎只能列表的每一项里面只能显示一行数据。网上有重写arrayAdapter的方法实现了自定义每一列,但是发现使用SimpAdapter可以很容易的实现自定义列表中的每一行的布局。
首先我们先看最终的效果图:
这个页面的ListView的每一项的样式比较复杂,左边是一张图片,右边又分为上面显示姓名,下面显示年龄。
好的,现在看下具体的实现步骤
首先需要来看main_activity, 一个ListView是必须的。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context="com.example.lolli.listviewdemo.MainActivity"> <ListView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/listView" android:layout_alignParentTop="true" android:layout_alignParentStart="true" /> </RelativeLayout>
列表的每一项的样式需要我们自己定义,看看定义的item文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageView android:id="@+id/tm_img" android:src="@drawable/tm" android:layout_width="100dp" android:layout_height="100dp" /> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:text="姓名:" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tm_name" android:text="天明" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:text="年龄:" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/tm_age" android:text="19" android:textSize="30sp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> </LinearLayout> </LinearLayout>
布局比较乱,有更好的方式来定于这个布局,但是这个不是重点,重点是加粗标红的那三个控件的id,那三个控件其实就是我们页面真正要显示内容的三个控件
现在我们再来看下最重要的Activity
package com.example.lolli.listviewdemo; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.ListView; import android.widget.SimpleAdapter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class MainActivity extends AppCompatActivity { private ListView listView; // 定义一个SimpleAdapter private SimpleAdapter simpleAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化控件 listView = (ListView) findViewById(R.id.listView); /** * Constructor * * @param context 上下文 * @param data 数据源 (List<Map<String, Object>>) 形式 * @param resource 每一项的布局文件 * @param from 对应的布局文件中的控件id * item. * @param to resource里要放的值的控件id */ int[] layoutId = {R.id.tm_img, R.id.tm_name, R.id.tm_age}; String[] from = {"pic", "name", "age"}; simpleAdapter = new SimpleAdapter(this, creatDate(), R.layout.item, from, layoutId); listView.setAdapter(simpleAdapter); } /** * 封装数据 * @return * 显示的数据源 */ private List<Map<String, Object>> creatDate (){ List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(); for (int i = 0; i<20; i++){ Map<String, Object> map = new HashMap<String, Object>(); map.put("pic", R.drawable.tm); map.put("name", "天明" + i); map.put("age", 18 + i); dataList.add(map); } return dataList; } }
这个说明一下SimpAdapter这个方法的几个参数
context : 上下文 这个很好理解,就当前页面吧 这里就是this
data: 数据源,这个也好理解,注意格式,是一个map的集合
resource: 这个值的是我们自定义的item那个布局文件
from: from是一个string类型的数组,这个数组里面的的数据跟to里面的id是一一对应的,但是名字我们自己取,只是我们在封装数据的时候,注意数据map的key必须 和form数组里面的名称一样 (个人认为在这里from就是页面显示与数据源之间的桥梁)
to : to是一个int类型的数组,里面其实就是封装的我item那个布局文件里面那三个要显示数据的空间id