ListView(2)SimpleAdapter与SimpleCursorAdapter详解

版权声明:转载请说明出处:http://blog.csdn.net/yhaolpz https://blog.csdn.net/yhaolpz/article/details/51635860

SimpleAdapter

官方定义:

An easy adapter to map static data to views defined in an XML file.
一个简单的适配器,将静态数据映射到一个XML文件中定义的视图。

上面定义有两点引起了我的注意:简单、静态数据。我想知道设计人员在设计这个适配器的时候为什么把它叫做简单适配器,简单这个形容词描述的是什么属性?静态数据的意思是只能绑定已经赋具体值的数据吗?通过对SimpleAdapter的使用演绎也许能得到答案。

数据适配器的使用步骤:

  1. 新建数据适配器
  2. 添加数据源到适配器
  3. 视图加载适配器

首先要了解新建SimpleAdapter涉及到的参数:

这里写图片描述

构造函数的参数列表及含义:

context: 上下文
data: 数据源, 类型为Map组成的List集合,每一个Map对应ListView中的一个Item,Map中的所有String类型的key组成的一个字符串数组就是参数from,key的作用就是与item关联起来。
resource: item的布局文件,其中至少要有参数to数组中的所有视图
from: 将被添加到与每个Item相关联的映射的列名称列表,data参数中Map的String类型键名组成的字符串数组
to: 显示与from数组对应数据的视图ID,这些视图都存在于resource指定的Item布局文件中

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/imv"
        android:layout_width="0dp"
        android:layout_weight="1"
        android:layout_height="70dp"
       android:background="#6523"/>
    <TextView
        android:id="@+id/cont"
        android:layout_width="0dp"
        android:layout_weight="4"
        android:layout_height="70dp"
        android:background="#66e21157"/>
    </LinearLayout>

MainActivity.java文件代码如下:

package com.example.listview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
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 mListView;
    private List<Map<String,Object>>mData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.listView);
        //准备数据源
        mData = new ArrayList<Map<String,Object>>();
        for(int i = 0;i<20;i++) {
            Map<String,Object> itemData = new HashMap<String,Object>();
            itemData.put("pic", R.mipmap.ic_launcher);
            itemData.put("text", "content" + i);
            mData.add(itemData);
        }
        //准备构造SimpleAdapter的参数
        String[] from = new String[]{"pic","text"};
        int[] to = new int[]{R.id.imv, R.id.cont};

        //1.新建数据适配器  // 2.添加数据源到适配器
        SimpleAdapter adapter = new SimpleAdapter(this, mData,R.layout.item, from, to);

        //3.视图加载适配器
        mListView.setAdapter(adapter);
    }
}

运行效果如下:

这里写图片描述

SimpleCursorAdapter

官方解释:

An easy adapter to map columns from a cursor to TextViews or ImageViews defined in an XML file.
一个简单的适配器,将游标中的数据映射到布局文件中的TextView控件或者ImageView控件中。

对比SimpleAdapter,不同之处就是SimpleCursorAdapter的数据源来源变了,SimpleAdapter针对的数据是静态数据,SimpleCursorAdapter针对的数据则是游标数据。同样先看SimpleCursorAdapter的构造方法:

这里写图片描述

构造函数的参数列表及含义:

context: 上下文
layout: item的布局文件,其中至少要有参数to数组中的所有视图
c: 数据库游标,如果游标不可用,则可为空
from: 一个列名称列表,标志着绑定到视图的数据,如果游标不可用,则可为空
to: 用来展示from数组中数据的视图,如果游标不可用,则可为空
flags: 用来确定适配器行为的标志

Item布局为系统布局android.R.layout.simple_expandable_list_item_2,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<TwoLineListItem xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:paddingTop="2dip"
    android:paddingBottom="2dip"
    android:paddingStart="?android:attr/expandableListPreferredItemPaddingLeft"
    android:mode="twoLine"
>
    <TextView android:id="@android:id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="6dip"
        android:textAppearance="?android:attr/textAppearanceListItem"
        android:textAlignment="viewStart"
    />
    <TextView android:id="@android:id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@android:id/text1"
        android:layout_alignStart="@android:id/text1"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textAlignment="viewStart"
    />
</TwoLineListItem>

MainActivity.java文件代码如下:

package com.example.listview;

import android.database.Cursor;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {
    private ListView mListView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mListView = (ListView) findViewById(R.id.listView);
        //准备数据源
        Cursor cursor = this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
        //准备新建SimpleCursorAdapter的构造参数
        String[] from = new String[]{ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.HAS_PHONE_NUMBER};
        int[] to = new int[]{android.R.id.text1,android.R.id.text2};
        //1.新建数据适配器  // 2.添加数据源到适配器
        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                android.R.layout.simple_expandable_list_item_2,
                cursor, from, to,
                SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);


        //3.视图加载适配器
        mListView.setAdapter(adapter);
    }
}

注意清单文件中要设置读取联系人权限:

 <uses-permission android:name="android.permission.READ_CONTACTS"/>

运行效果如下:

这里写图片描述

上面 SimpleAdapter 绑定了图片资源,那么 SimpleCursorAdapter 可以绑定图片资源吗?首先来看下 SimpleAdapter 中是怎样绑定图片资源的,可以看到在 mData 中是通过资源 ID : R.mipmap.ic_launcher 找到图片资源的,ok~接着 SimpleCursorAdapter 获取联系人信息的例子,怎么获取联系人头像呢?联系人信息是存储在数据库的,一般来说,从数据库中可以获取到 资源 Uri ,尝试:

 //准备数据源
            Cursor cursor = this.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
            //准备新建SimpleCursorAdapter的构造参数
            String[] from = new String[]{ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.PHOTO_THUMBNAIL_URI};
            int[] to = new int[]{R.id.cont, R.id.imv};
            //1.新建数据适配器  // 2.添加数据源到适配器
            SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
                    R.layout.item,
                    cursor, from, to,
                    SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

            //3.视图加载适配器
            mListView.setAdapter(adapter);

把布局换成了 SimpleAdapter 例中的图文布局,from 数组中把 ContactsContract.Contacts.HAS_PHONE_NUMBER 更换为 ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,这时就会显示出联系人头像:
这里写图片描述

没设置过头像的联系人当然就不显示了,除了 PHOTO_THUMBNAIL_URI ,再看看其他的与头像相关的值:

这里写图片描述

PHOTO_URI 应该是高清大图了,另外两个 ID 是资源 ID 吗?不是说存储在数据库中一般提供的是 Uri 吗?尝试一下,把 PHOTO_THUMBNAIL_URI 换成 PHOTO_ID,程序崩溃,报错内容为:

android.content.res.Resources$NotFoundException

看到这个我就放心了,就乖乖的使用 Uri 就好了,因为一般在 mipmap 或 drawable 中的资源才通过资源 ID 来访问,当然如果非要用 ID 来访问也不是不可能的,只不过要对 ID 进行加工,具体方法可百度,不过在可以使用 Uri 的情况下再去周折,那就纯碎多次一举了。

总结:SimpleAdapter、SimpleCursorAdapter都被称为简单适配器,回到一开始的问题,“简单”到底指的是什么简单?如果跟自定义BaseAdapter相比,指出BaseAdapter的优点似乎就是答案。但是看起来更简单的ArrayAdapter数组适配器都没有用“Simple”形容,为什么这两个适配器用“Simple”形容?其实现在提出这个问题的时候答案我并不知道,但是不能放走它。各位等我去查…或者…你告诉我…

猜你喜欢

转载自blog.csdn.net/yhaolpz/article/details/51635860