Android 之 ListView 绑定数据源

在 android 开发中 ListView 是比较常用的组件,它以列表的形式展示具体内容,并且能够根据数据的长度自适应显示。

ListView 列表显示需要的三个元素:

  • ListView 中用来显示每列数据的 View 。

  • 填充 View 的数据或者图片等。

  • 链接数据与 ListView 的适配器

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

下面介绍几种常用的适配器:

  • BaseAdapter:通用的基础适配器。

  • ArrayAdapter:用来绑定一个数组,支持泛型操作。最为简单,只能显示一行数据。

  • SimpleAdapter:用来绑定在 xml 中定义的控件对应的数据。扩充性较好,可以自定义各种效果。

  • SimpleCursorAdapter:用来绑定游标得到的数据。可以认为是 SimpleAdapter 对数据库的简单结合,可以方面的把数据库的内容以列表的形式展示出来。

下面分别介绍几种常用绑定数据的方法:

1、最简单的绑定数据方法:通过android:entries属性绑定数据源

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context="${relativePackage}.${activityClass}" >
  6. <ListView
  7. android:id="@+id/listView1"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:entries="@array/arrayname" >
  11. </ListView>
  12. </RelativeLayout>

xlm文件配置:res–>values–>array.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3. <string-array name="arrayname">
  4. <item>张三</item>
  5. <item>李四</item>
  6. <item>王五</item>
  7. <item>赵六</item>
  8. </string-array>
  9. </resources>

运行结果如图:

2、ArrayAdapter 绑定数组资源

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context="${relativePackage}.${activityClass}" >
  6. <ListView
  7. android:id="@+id/listView1"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent">
  10. </ListView>
  11. </RelativeLayout>

下面内容是自定义一个数组绑定到 ListView 上面,当然数组可以是各种资源。下面以字符串数组为例说明:

  1. public class ArrayAdapterActivity extends Activity implements OnItemClickListener {
  2. private ArrayAdapter<String> adapter;
  3. private ListView mListView;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.activity_array_adapter);
  8. String[] names = {"测试ArrayAdapter1", "测试ArrayAdapter2", "测试ArrayAdapter3", "测试ArrayAdapter4"};
  9. adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, names);
  10. mListView = (ListView)findViewById(R.id.listView1);
  11. mListView.setAdapter(adapter);
  12. }
  13. @Override
  14. public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  15. // TODO Auto-generated method stub
  16. Toast.makeText(this, "你点击的是第:" + position + "个", 2000).show();
  17. }
  18. }

运行结果如图:

3、SimpleAdapter 绑定数据相对灵活一些,可以自定义各种样式绑定不同的数据源

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. tools:context="${relativePackage}.${activityClass}" >
  6. <ListView
  7. android:id="@+id/listView1"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent" >
  10. </ListView>
  11. </RelativeLayout>

自定义列表样式:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:padding="10dp"
  6. android:gravity="center_vertical"
  7. android:orientation="horizontal" >
  8. <ImageView
  9. android:id="@+id/imageView1"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"/>
  12. <TextView
  13. android:id="@+id/textView1"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:layout_weight="1"
  17. android:text="TextView" />
  18. <ImageView
  19. android:id="@+id/imageView2"
  20. android:layout_width="wrap_content"
  21. android:layout_height="wrap_content"
  22. android:src="@drawable/arrow_content" />
  23. </LinearLayout>

一下数据源也可以是 xml 文件等数据源,当然也可以是网络请求数据。

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.activity_simple_adapter);
  5. SimpleAdapter adapter = new SimpleAdapter(this, getData(), R.layout.list_item,
  6. new String[] {"title", "img"},
  7. new int[] {R.id.textView1, R.id.imageView1});
  8. ListView mListView = (ListView)findViewById(R.id.listView1);
  9. mListView.setAdapter(adapter);
  10. mListView.setOnItemClickListener(this);
  11. }
  12. private List<Map<String, Object>> getData() {
  13. List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
  14. Map<String, Object> map = new HashMap<String, Object>();
  15. map.put("title", "测试SimpleAdapter1");
  16. map.put("img", R.drawable.ic_launcher);
  17. list.add(map);
  18. map = new HashMap<String, Object>();
  19. map.put("title", "测试SimpleAdapter2");
  20. map.put("img", R.drawable.ic_launcher);
  21. list.add(map);
  22. map = new HashMap<String, Object>();
  23. map.put("title", "测试SimpleAdapter3");
  24. map.put("img", R.drawable.ic_launcher);
  25. list.add(map);
  26. return list;
  27. }
  28. @Override
  29. public void onItemClick(AdapterView<?> parent, View view, int position,
  30. long id) {
  31. // TODO Auto-generated method stub
  32. Map<String, Object> map = (Map<String, Object>)parent.getItemAtPosition(position);
  33. Toast.makeText(this, "你点击的是第:" + position + "个 ," + map.get("title"), 2000).show();
  34. }

4、自定义 Adapter,这也是最为灵活的方法,下面仍然用菜单列表为例:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:background="@color/bgMainColor"
  6. android:orientation="vertical" >
  7. <ListView
  8. android:id="@+id/listView"
  9. android:layout_width="match_parent"
  10. android:layout_height="match_parent"
  11. android:layout_marginTop="@dimen/dp20" />
  12. </LinearLayout>

后台代码

  1. public class MeFragment extends Fragment implements OnItemClickListener {
  2. private ListView mListView;
  3. private MenuAdapter menuAdapter;
  4. @Override
  5. public View onCreateView(LayoutInflater inflater, ViewGroup container,
  6. Bundle savedInstanceState) {
  7. View view = inflater.inflate(R.layout.fragment_me, null);
  8. mListView = (ListView) view.findViewById(R.id.listView);
  9. mListView.setDivider(new ColorDrawable(Color.LTGRAY));
  10. mListView.setDividerHeight(1);
  11. menuAdapter = new MenuAdapter(getActivity(), getDataList());
  12. mListView.setAdapter(menuAdapter);
  13. mListView.setOnItemClickListener(this);
  14. return view;
  15. }
  16. /**
  17. * 获得菜单数据
  18. * @return
  19. */
  20. public List<MenuBean> getDataList() {
  21. List<MenuBean> menuList = new ArrayList<>();
  22. MenuBean bean = new MenuBean("手机号变更", HelpActivity.class);
  23. menuList.add(bean);
  24. bean = new MenuBean("修改登录密码", HelpActivity.class);
  25. menuList.add(bean);
  26. bean = new MenuBean("设置/修改交易密码", HelpActivity.class);
  27. menuList.add(bean);
  28. bean = new MenuBean("设置/修改支付宝账号", HelpActivity.class);
  29. menuList.add(bean);
  30. bean = new MenuBean("我的钱包", HelpActivity.class);
  31. menuList.add(bean);
  32. return menuList;
  33. }
  34. @Override
  35. public void onItemClick(AdapterView<?> parent, View view, int position,
  36. long id) {
  37. // TODO Auto-generated method stub
  38. MenuBean item = (MenuBean) parent.getItemAtPosition(position);
  39. Intent intent = new Intent();
  40. intent.setClass(getActivity(), item.getCls());
  41. startActivity(intent);
  42. }
  1. /**
  2. * 菜单栏
  3. * @author mategnfei
  4. */
  5. public class MenuBean implements Serializable {
  6. private static final long serialVersionUID = 1L;
  7. private Integer icon;
  8. private String title;
  9. private String separator = null;//空-菜单组之间的上下间隔;默认false,没有间隔
  10. private Class<?> cls = null;//点击跳转的Activity
  11. public MenuBean() {
  12. }
  13. public Integer getIcon() {
  14. return icon;
  15. }
  16. public void setIcon(Integer icon) {
  17. this.icon = icon;
  18. }
  19. public MenuBean(Integer icon, String title, String separator, Class<?> cls) {
  20. super();
  21. this.icon = icon;
  22. this.title = title;
  23. this.separator = separator;
  24. this.setCls(cls);
  25. }
  26. public MenuBean(String title, String separator, Class<?> cls) {
  27. super();
  28. this.title = title;
  29. this.separator = separator;
  30. this.setCls(cls);
  31. }
  32. public MenuBean(String title, Class<?> cls) {
  33. super();
  34. this.title = title;
  35. this.setCls(cls);
  36. }
  37. public String getTitle() {
  38. return title;
  39. }
  40. public void setName(String title) {
  41. this.title = title;
  42. }
  43. public String getSeparator() {
  44. return separator;
  45. }
  46. public void setSeparator(String separator) {
  47. this.separator = separator;
  48. }
  49. public Class<?> getCls() {
  50. return cls;
  51. }
  52. public void setCls(Class<?> cls) {
  53. this.cls = cls;
  54. }
  55. }
  1. /**
  2. * 菜单栏适配器
  3. * @author matengfei
  4. */
  5. public class MenuAdapter extends BaseAdapter {
  6. private ViewHolder holder;
  7. private List<MenuBean> menuList;
  8. private Context context;
  9. private MenuBean bean;
  10. public MenuAdapter(Context context, List<MenuBean> mList) {
  11. this.context = context;
  12. this.menuList = mList;
  13. }
  14. @Override
  15. public int getCount() {
  16. // TODO Auto-generated method stub
  17. return menuList.size();
  18. }
  19. @Override
  20. public Object getItem(int position) {
  21. // TODO Auto-generated method stub
  22. return menuList.get(position);
  23. }
  24. @Override
  25. public long getItemId(int position) {
  26. // TODO Auto-generated method stub
  27. return position;
  28. }
  29. @Override
  30. public View getView(int position, View convertView, ViewGroup parent) {
  31. if(convertView == null) {
  32. holder = new ViewHolder();
  33. convertView = LayoutInflater.from(context).inflate(R.layout.item_menu, null);
  34. holder.ivIcon = (ImageView) convertView.findViewById(R.id.iv_icon);
  35. holder.tvTitle = (TextView)convertView.findViewById(R.id.tv_title);
  36. convertView.setTag(holder);
  37. } else {
  38. holder = (ViewHolder) convertView.getTag();
  39. }
  40. bean = menuList.get(position);
  41. if(bean != null) {
  42. if(bean.getSeparator() != null) {
  43. return LayoutInflater.from(context).inflate(R.layout.item_null, null);
  44. }
  45. if (bean.getIcon() == null) {
  46. holder.ivIcon.setVisibility(View.GONE);
  47. } else {
  48. holder.ivIcon.setBackgroundResource(bean.getIcon());
  49. }
  50. holder.tvTitle.setText(bean.getTitle());
  51. }
  52. return convertView;
  53. }
  54. private static class ViewHolder {
  55. ImageView ivIcon;
  56. TextView tvTitle;
  57. }
  58. }

运行结果如图:

(完)