王学岗ListView和源码解析(二)

在本文中我们介绍ListView第二个的适配器——SimpleAdapter;
与ArrayAdapter只能显示单列的不同,SimpleAdapter可以显示多列。
下面我们使用SimpleAdapter在ListView中显示一个人的信息,包括name,number。
下面看下源码:

package com.example.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.ArrayAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {

    private ListView lv_list;
    private List<Map<String, String>> data;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv_list = (ListView) findViewById(R.id.lv_list);
        data = new ArrayList<Map<String, String>>();
        intData();
        // 创建适配器
        SimpleAdapter adapter = new SimpleAdapter(this,// 上下文,不多解释
                data,// 填充到listView里面的数据
                R.layout.list_item,// 每一行的布局文件
                new String[] {"name","number"}, //根据每一行的map里面的key,得到里面的值
                new int[] {R.id.tv_name,R.id.tv_number}//根据ID,去吧每一个数据填充到对应的个控件上
        );
        lv_list.setAdapter(adapter);
    }

    // 初始化数据
    private void intData() {
        for (int i = 0; i < 150; i++) {
            Map<String, String> item = new HashMap<String, String>();
            item.put("name", "周瑜帅" + "-" + i);
            item.put("number", String.valueOf(36+i));
            data.add(item);
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    <TextView
        android:id="@+id/tv_name"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
          />

    <TextView
        android:id="@+id/tv_number"
        android:layout_width="140dp"
        android:layout_height="wrap_content"
         />

</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/LinearLayout1"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <ListView
        android:id="@+id/lv_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

源码解析:与arraydapter极为类似,也是BaseAdapter的子类

我们直接看getView方法,其他的方法参考(一);

public View getView(int position, View convertView, ViewGroup parent) {
    return createViewFromResource(position, convertView, parent, mResource);
}

private View createViewFromResource(int position, View convertView,
        ViewGroup parent, int resource) {
    View v;
    if (convertView == null) {
        v = mInflater.inflate(resource, parent, false);
    } else {
        v = convertView;
    }

    bindView(position, v);

    return v;
}

多了一行代码bindView(position, v);
我们仔细来分析

private void bindView(int position, View view) {
    final Map dataSet = mData.get(position);//根据行号,得到对应的map
    if (dataSet == null) {
        return;
    }

    final ViewBinder binder = mViewBinder;
    final String[] from = mFrom;
    final int[] to = mTo;
    final int count = to.length;

    for (int i = 0; i < count; i++) {
        final View v = view.findViewById(to[i]);//根据对应的ID找到对应的控件
        if (v != null) {
            final Object data = dataSet.get(from[i]);//根据K(name,number)的值拿到相应的数据
            String text = data == null ? "" : data.toString();
            if (text == null) {
                text = "";
            }

            boolean bound = false;
            if (binder != null) {
                bound = binder.setViewValue(v, data, text);
            }

            if (!bound) {
                if (v instanceof Checkable) {//对控件的类型进行判断
                    if (data instanceof Boolean) {
                        ((Checkable) v).setChecked((Boolean) data);
                    } else if (v instanceof TextView) {
                        // Note: keep the instanceof TextView check at the bottom of these
                        // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                        setViewText((TextView) v, text);
                    } else {
                        throw new IllegalStateException(v.getClass().getName() +
                                " should be bound to a Boolean, not a " +
                                (data == null ? "<unknown type>" : data.getClass()));
                    }
                } else if (v instanceof TextView) {
                    // Note: keep the instanceof TextView check at the bottom of these
                    // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                   setViewText((TextView) v, text);//调用该方法赋值
                } else if (v instanceof ImageView) {
                    if (data instanceof Integer) {
                        setViewImage((ImageView) v, (Integer) data);                            
                    } else {
                        setViewImage((ImageView) v, text);
                    }
                } else {
                    throw new IllegalStateException(v.getClass().getName() + " is not a " +
                            " view that can be bounds by this SimpleAdapter");
                }
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值