ListView与Adapter

来源:互联网 发布:尽人事知天命下一句 编辑:程序博客网 时间:2024/05/19 03:44

ListView是用来交互和展示数据的,但是数据的类型很多,如果让ListView为每一种数据都进行适配的话那么ListView是比较臃肿的,所以就需要Adapter去帮助我们适配数据源。

Adapter是一个接口,Adapter常用的实现类如下
ArrayAdapter: 简单,易用的Adapter,通常用于将数组或者List集合的多个值包装成多个列表项。

SimpleAdapter: 并不简单,功能强大的Adapter,可用于将List集合的多个对象包装成多个列表项。

SimpleCursorAdapter:与SimpleAdapter基本相似,只是用于包装Cursor提供的数据。

BaseAdapter: 通常用于被扩展。扩展BaseAdapter可以对各列表项进行最大限度的定制。

listView与ArrayAdapter

使用步骤:
1. 创建并绑定ListView。
2. 创建ArrayAdapter。
3. 设置ListView的Adapter。

ArrayAdapter有两个构造方法:
ArrayAdapter(Context context, int textViewResourceId, List objects)
ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)
其中resource用于布局文件资源。textViewResourceId设置TextView样式。

textViewResourceId常用的参数为:
simple_list_item_1: 每个列表项都是一个普通的TextView。
simple_list_item_2: 有两个TextView,分两行显示。
simple_list_item_multiple_choice: 每个列表项都带多选框。
simple_list_item_single_choice :每个列表项都带单选框。

示例程序
这里写图片描述

public class MainActivity extends Activity {    private String[] data = {"apple", "banana", "orange", "watermelon", "pear"};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, data);        ListView listView = (ListView) findViewById(R.id.list_view);        listView.setAdapter(adapter);    }}

xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent">    <ListView        android:id="@+id/list_view"        android:layout_width="match_parent"        android:layout_height="match_parent"></ListView></LinearLayout>

ListView与SimpleAdapter

通过ArrayAdapter实现Adapter虽然简单,但是ArrayAdapter得功能比较有限。如果需要实现更复杂的功能就需要使用SimpleAdapter了。
SimpleAdapter的构造方法为:

public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,            @LayoutRes int resource, String[] from, @IdRes int[] to)

第二个参数: 该集合中每一个Map<String, ?> 对象生成一个列表项。
第三个参数: 指定一个界面布局的ID。
第四个参数: 决定提取Map<String , ?> 中的对象的哪些key对应的value来生成列表项。
第五个参数: 决定填充哪些组件。

示例程序
这里写图片描述

xml

<?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">    <ListView        android:id="@+id/list_view"        android:layout_width="match_parent"        android:layout_height="wrap_content"></ListView></LinearLayout>

新建一个simple_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="horizontal" android:layout_width="match_parent"    android:layout_height="wrap_content">    <ImageView        android:id="@+id/header"        android:paddingLeft="10dp"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <LinearLayout        android:orientation="vertical"        android:layout_width="match_parent"        android:layout_height="wrap_content">        <TextView            android:id="@+id/name"            android:textSize="20dp"            android:textColor="#f0f"            android:paddingLeft="10dp"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />        <TextView            android:id="@+id/desc"            android:textSize="14dp"            android:paddingLeft="10dp"            android:layout_width="wrap_content"            android:layout_height="wrap_content" />    </LinearLayout></LinearLayout>

MainActivity

public class MainActivity extends Activity {    private String[] name = {"apple", "banana", "orange", "watermelon", "pear"};    private String[] descs = {"苹果好吃", "香蕉好吃", "橘子好处", "西瓜好吃", "梨好吃"};    //随便找的图标    private int[] imageId = new int[]{R.drawable.ic_launcher, R.drawable.ic_launcher,            R.drawable.ic_launcher, R.drawable.ic_launcher, R.drawable.ic_launcher};    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.content_main);        List<Map<String, Object>> listItems = new ArrayList<>();        for (int i = 0; i < name.length; i++) {            Map<String, Object> listItem = new HashMap<>();            listItem.put("header", imageId[i]);            listItem.put("name", name[i]);            listItem.put("desc", descs[i]);            listItems.add(listItem);        }        SimpleAdapter simpleAdapter = new SimpleAdapter(this, listItems, R.layout.simple_item,                new String[]{"name", "header", "desc"},                new int[]{R.id.name, R.id.header, R.id.desc});        ListView list = (ListView) findViewById(R.id.list_view);        list.setAdapter(simpleAdapter);    }}

扩展BaseAdapter

扩展BaseAdapter需要重写4个方法。
getCount():该方法的返回值控制该Adapter将会包含多少个列表项。
getItem(int position):该方法的返回值决定第position处的列表项的内容。
getItemId(int position):该方法的返回值决定第position处的列表项的ID。
getView(int position, View convertView, ViewGroup parent):这里最重要的方法,该方法的返回值决定第position处的列表项组件。

public class MyAdapter extends BaseAdapter {    @Override    public int getCount() {        return 0;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        return null;    }}

getView的优化

要理解getView的优化首先应理解 Recycle机制。这里推荐郭霖的 Android ListView工作原理完全解析,带你从源码的角度彻底理解
没有任何优化:

@Override        public View getView(int position, View convertView, ViewGroup parent) {            View item = mInflater.inflate(R.layout.list_item, null);            ImageView img = (ImageView)item.findViewById(R.id.img)             TextView title = (TextView)item.findViewById(R.id.title);            TextView info = (TextView)item.findViewById(R.id.info);            img.setImageResource(R.drawable.ic_launcher);            title.setText("Hello");            info.setText("world");            return item;        }

每加载一个数据时都会重新创建View和绑定资源操作。一旦数据量多的时候会严重影响性能。

优化一:利用缓存中的View也就是convertView

public View getView(int position, View convertView, ViewGroup parent) {            if(convertView == null)            {                convertView = mInflater.inflate(R.layout.list_item, null);            }            ImageView img = (ImageView)convertView.findViewById(R.id.img)             TextView title = (TextView)convertView.findViewById(R.id.title);            TextView info = (TextView)ConvertView.findViewById(R.id.info);            img.setImageResource(R.drawable.ic_launcher);            title.setText("Hello");            info.setText("world");            return convertView;        }

优化二:利用静态类优化绑定资源的操作

//在外面先定义,ViewHolder静态类    static class ViewHolder    {        public ImageView img;        public TextView title;        public TextView info;    }//然后重写getView        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder holder;            if(convertView == null)            {                holder = new ViewHolder();                convertView = mInflater.inflate(R.layout.list_item, null);                holder.img = (ImageView)item.findViewById(R.id.img)                 holder.title = (TextView)item.findViewById(R.id.title);                holder.info = (TextView)item.findViewById(R.id.info);                convertView.setTag(holder);            }else            {                holder = (ViewHolder)convertView.getTag();                holder.img.setImageResource(R.drawable.ic_launcher);                holder.title.setText("Hello");                holder.info.setText("World");            }            return convertView;        }

示例程序
这里写图片描述

activicy_main和simple_item直接用simpleAdapter示例程序的。

MainActivity:

public class MainActivity extends Activity {    private List<Map<String, Object>> data;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.content_main);        data = getData();        MyAdapter myAdapter = new MyAdapter(this);        ListView list = (ListView) findViewById(R.id.list_view);        list.setAdapter(myAdapter);    }    private List<Map<String, Object>> getData(){        List<Map<String, Object>> listItems = new ArrayList<>();        for (int i = 0; i < 20; i++) {            Map<String, Object> listItem = new HashMap<>();            listItem.put("header", R.drawable.ic_launcher);            listItem.put("name", i + "Android机器人");            listItem.put("desc", "Android机器人");            listItems.add(listItem);        }        return listItems;    }    static class ViewHolder{        public ImageView header;        public TextView name;        public TextView desc;    }    public class MyAdapter extends BaseAdapter {        private LayoutInflater mInflater;        public MyAdapter(Context context){            this.mInflater = LayoutInflater.from(context);        }        @Override        public int getCount() {            return 20;        }        @Override        public Object getItem(int position) {            return position;        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            ViewHolder holder = null;            if (convertView == null){                holder = new ViewHolder();                convertView = mInflater.inflate(R.layout.simple_item, null);                holder.header = (ImageView) convertView.findViewById(R.id.header);                holder.name = (TextView) convertView.findViewById(R.id.name);                holder.desc = (TextView) convertView.findViewById(R.id.desc);                convertView.setTag(holder);            }else{                holder = (ViewHolder) convertView.getTag();            }            holder.header.setBackgroundResource((Integer) data.get(position).get("header"));            holder.name.setText((String) data.get(position).get("name"));            holder.desc.setText((String) data.get(position).get("desc"));            return convertView;        }    }}

参考书籍博客

《第一行代码》
《Android疯狂讲义》第三版
Android ListView工作原理完全解析,带你从源码的角度彻底理解
android应用开发全程实录-你有多熟悉listview?
android ListView详解
Android杂谈–ListView之BaseAdapter的使用
博客内容是我阅读以上资料加上自己的理解所得,有部分摘抄自以上资料,侵删。

1 0
原创粉丝点击