Adapter介绍
Adapter是将数据绑定到UI界面上的桥接类。Adapter负责创建显示每个项目的子View和提供对下层数据的访问。
支持Adapter绑定的UI控件必须扩展AdapterView抽象类。创建自己的继承自AdapterView的控件和创建新的Adapter类来绑定它们是可能的。
一些Android提供的Adapter介绍
在多数情况下,你不需要白手创建自己的Adapter。Android提供了一系列Adapter来将数据绑定到UI Widget上。
因为Android负责提供数据和选择用于显示每个项目的View,所以Adapter能快速地修改要绑定的控件的外观和功能。下面的列表显示了两个最有用和最通用的本地Adapter:
❑ ArrayAdapter
ArrayAdapter是一个绑定View到一组对象的通用类。默认情况下,ArrayAdapter绑定每个对象的toString值到在layout中预先定义的TextView控件上。可变通的,构造函数允许你使用更加复杂的layout或者通过重写getView方法来扩展类从而使用TextView的替代物(如ImageView或嵌套的layout)。
❑ SimpleCursorAdapter
SimpleCursorAdapter绑定View到Content Provider查询返回的游标上。指定一个XML layout定义,然后将数据集中的每一列的值绑定到layout中的一个View上。
接下来的章节将深入挖掘这些Adapter类的细节。例子中,提供了绑定数据到ListView上,尽管这个逻辑会和其他一些AdapterView类(如Spinner和Gallery)工作的一样。
使用Adapter进行数据绑定
将Adapter应用到继承自AdapterView类上,你需要调用View的setAdapter方法,传入一个Adapter实例,如下面的片段所示:
ArrayList<String> myStringArray = new ArrayList<String>();
ArrayAdapter<String> myAdapterInstance;
int layoutID = android.R.layout.simple_list_item_1;
myAdapterInstance = new ArrayAdapter<String>(this, layoutID, myStringArray);
myListView.setAdapter(myAdapterInstance);
这个片段显示了最简单的情况,将数组中的字符串绑定到ListView中用于显示每个项目的简单TextView控件上。
接下来的第一个例子显示了如何绑定一组复杂的对象到ListView上,使用一个自定义的layout。第二个例子显示了如何使用SimpleCursorAdapter来绑定查询结果到ListView中的自定义layout上。
在android开发中列表的使用是十分常见的。google对列表的封装使列表既有显示传统文本列表的能力,也有加入了诸如选择项、复选项等处理事件的能力。这里写一些我这几天对这个问题的理解。
在android的api中,LIST和adapter都被放在了android.widget包内。包内的具体结构我这里先不展示了,主要侧重列表和adapter。adapter的作用就是将要在列表内显示的数据和列表本身结合起来。列表本身只完成显示的作用,其实他就是继承自VIEWGROUP类。但是他又有一个独特的函数就是setAdapter()就是完成了view和adapter的结合。adapter如同其本身含义,其实就是一个适配器,他可以对要显示的数据进行统一的封装,主要是将数据变成view提供给list。
我们先来看看adapter的体系:
public interface Adapter----0层(表示继承体系中的层次)
public interface ExpandableListAdapter---(无所谓层次因为没有其他接口继承实现它)
这是adapter的始祖,其他个性化的adapter均实现它并加入自己的接口。
public interface ListAdapter----1层
public interface SpinnerAdapter----1层
public interface WrapperListAdapter----2层(实现ListAdapter)
以上接口层面上的体系已经完了。可以看出来作为widget view的桥梁adapter其实只分为2种:ListAdapter和SpinnerAdapter以及ExpandableListAdapter。也就是说所有widget也就是基于list和spinne与ExpandableList三种view形式的。
由于在实际使用时,我们需要将数据加入到Adapter,而以接口形式呈现的adapter无法保存数据,于是Adapter就转型为类的模式。
public abstract class BaseAdapter----2层(实现了ListAdapter和SpinnerAdapter)
以抽象类的形式出现构造了类型态下的顶层抽象,包容了List和Spinner
public class ArrayAdapter----3层
public class SimpleAdapter---3层
public class CursorAdapter----3层(CursorAdapter其后还有子类这里先不探讨)
基本体系有了之后,让我们看看顶层Adapter里有哪些方法(只列举常用的):
abstract Object getItem(int position)
abstract int getCount()
abstract long getItemId(int position)
abstract int getItemViewType(int position)
abstract View getView(int position,View convertVeiw,ViewGroup parent)
以上是比较重要的方法,ArrayAdapter他们也是重新实现以上方法的。在实际的开发过程中,往往我们要自己做属于自己的Adapter,以上方法都是需要重新实现的。
使用ArrayAdapter定制To-Do List
这个例子将扩展To-Do List工程,以一个ToDoItem对象来储存每一个项目,包含每个项目的创建日期。
你将扩展ArrayAdapter类来绑定一组ToDoItem对象到ListView上,并定制用于显示每一个ListView项目的layout。
1. 返回到To-Do List工程。创建一个新的ToDoItem类来保存任务和任务的创建日期。重写toString方法来返回一个项目数据的概要。
package com.paad.todolist; import java.text.SimpleDateFormat; import java.util.Date; public class ToDoItem { String task; Date created; public String getTask() { return task; } public Date getCreated() { return created; } public ToDoItem(String _task) { this(_task, new Date(java.lang.System.currentTimeMillis())); } public ToDoItem(String _task, Date _created) { task = _task; created = _created; } @Override public String toString() { SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yy”); String dateString = sdf.format(created); return “(“ + dateString + “) “ + task; } }
2. 打开ToDoList Activity,修改ArrayList和ArrayAdapter变量的类型,储存ToDoItem对象而不是字符串。然后,你将修改onCreate方法来更新相应的变量初始化。你还需要更新onKeyListener处理函数来支持ToDoItem对象。
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://dxs376263348.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=private%20ArrayList%3CToDoItem%3E%20todoItems%3B%0Aprivate%20ListView%20myListView%3B%20%0Aprivate%20EditText%20myEditText%3B%20%0Aprivate%20ArrayAdapter%3CToDoItem%3E%20aa%3B%20%0A%40Override%20public%20void%20onCreate(Bundle%20icicle)%20%7B%0A%20super.onCreate(icicle)%3B%20%2F%2F%20Inflate%20your%20view%20setContentView(R.layout.main)%3B%20%2F%2F%20%20%0A%20Get%20references%20to%20UI%20widgets%20myListView%20%3D%20(ListView)findViewById(R.id.myListView)%3B%0A%20%20%20%20myEditText%20%3D%20(EditText)findViewById(R.id.myEditText)%3B%20%0A%20%20%20%20todoItems%20%3D%20new%20ArrayList%3CToDoItem%3E()%3B%20%0A%20%20%20%20int%20resID%20%3D%20R.layout.todolist_item%3B%20aa%20%3D%20new%20ArrayAdapter%3CToDoItem%3E(this%2C%20resID%2C%20todoItems)%3B%20%0A%20%20%20%20myListView.setAdapter(aa)%3B%0A%20myEditText.setOnKeyListener(new%20OnKeyListener()%20%7B%20%0Apublic%20boolean%20onKey(View%20v%2C%20int%20keyCode%2C%20KeyEvent%20event)%20%7B%0A%20if%20(event.getAction()%20%3D%3D%20KeyEvent.ACTION_DOWN)%0A%20%20%20if%20(keyCode%20%3D%3D%20KeyEvent.KEYCODE_DPAD_CENTER)%20%7B%20%0A%20%20%20ToDoItem%20newItem%3B%20newItem%20%3D%20new%20ToDoItem(myEditText.getText().toString())%3B%20todoItems.add(0%2C%20newItem)%3B%0A%20%20%20%20myEditText.setText(%E2%80%9C%E2%80%9D)%3B%20%0A%20%20%20%20aa.notifyDataSetChanged()%3B%20cancelAdd()%3B%20return%20true%3B%20%0A%20%20%20%20%20%20%7D%20%0A%20%20%20%20return%20false%3B%20%0A%20%20%20%20%7D%0A%20%20%7D)%3B%0A%20registerForContextMenu(myListView)%3B%20%0A%7D%20"></embed>
- private ArrayList<ToDoItem> todoItems;
- private ListView myListView;
- private EditText myEditText;
- private ArrayAdapter<ToDoItem> aa;
- @Override public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- Get references to UI widgets myListView = (ListView)findViewById(R.id.myListView);
- myEditText = (EditText)findViewById(R.id.myEditText);
- todoItems = new ArrayList<ToDoItem>();
- int resID = R.layout.todolist_item; aa = new ArrayAdapter<ToDoItem>(this, resID, todoItems);
- myListView.setAdapter(aa);
- myEditText.setOnKeyListener(new OnKeyListener() {
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- if (event.getAction() == KeyEvent.ACTION_DOWN)
- if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
- ToDoItem newItem; newItem = new ToDoItem(myEditText.getText().toString()); todoItems.add(0, newItem);
- myEditText.setText(“”);
- aa.notifyDataSetChanged(); cancelAdd(); return true;
- }
- return false;
- }
- });
- registerForContextMenu(myListView);
- }
3. 如果你运行Activity,它将显示每个to-do项目,如图5-3所示。
图5-3
4. 现在,你可以创建一个自定义的layout来显示每一个to-do项目。修改在第4章中创建的自定义layout,包含另外一个TextView,它将用于显示每个to-do项目的创建日期。
Xml代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://dxs376263348.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=%3C%3Fxml%20version%3D%E2%80%9D1.0%E2%80%9D%20encoding%3D%E2%80%9Dutf-8%E2%80%9D%3F%3E%20%0A%3CRelativeLayout%20xmlns%3Aandroid%3D%E2%80%9Dhttp%3A%2F%2Fschemas.android.com%2Fapk%2Fres%2Fandroid%E2%80%9D%20android%3Alayout_width%3D%E2%80%9Dfill_parent%E2%80%9D%20android%3Alayout_height%3D%E2%80%9Dfill_parent%E2%80%9D%20android%3Abackground%3D%E2%80%9D%40color%2Fnotepad_paper%E2%80%9D%3E%20%0A%3CTextView%20android%3Aid%3D%E2%80%9D%40%2Bid%2FrowDate%E2%80%9D%20android%3Alayout_width%3D%E2%80%9Dwrap_content%E2%80%9D%20android%3Alayout_height%3D%E2%80%9Dfill_parent%E2%80%9D%20android%3Apadding%3D%E2%80%9D10dp%E2%80%9D%20android%3Ascrollbars%3D%E2%80%9Dvertical%E2%80%9D%20android%3AfadingEdge%3D%E2%80%9Dvertical%E2%80%9D%20android%3AtextColor%3D%E2%80%9D%40color%2Fnotepad_text%E2%80%9D%20android%3Alayout_alignParentRight%3D%E2%80%9Dtrue%E2%80%9D%20%2F%3E%20%0A%3CTextView%20android%3Aid%3D%E2%80%9D%40%2Bid%2Frow%E2%80%9D%20android%3Alayout_width%3D%E2%80%9Dfill_parent%E2%80%9D%20android%3Alayout_height%3D%E2%80%9Dfill_parent%E2%80%9D%20android%3Apadding%3D%E2%80%9D10dp%E2%80%9D%20android%3Ascrollbars%3D%E2%80%9Dvertical%E2%80%9D%20android%3AfadingEdge%3D%E2%80%9Dvertical%E2%80%9D%20android%3AtextColor%3D%E2%80%9D%40color%2Fnotepad_text%E2%80%9D%20android%3Alayout_alignParentLeft%3D%E2%80%9D%40%2Bid%2FrowDate%E2%80%9D%20%2F%3E%20%3C%2FRelativeLayout%3E%20"></embed>
- <?xml version=”1.0” encoding=”utf-8”?>
- <RelativeLayout xmlns:android=”http://schemas.android.com/apk/res/android” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:background=”@color/notepad_paper”>
- <TextView android:id=”@+id/rowDate” android:layout_width=”wrap_content” android:layout_height=”fill_parent” android:padding=”10dp” android:scrollbars=”vertical” android:fadingEdge=”vertical” android:textColor=”@color/notepad_text” android:layout_alignParentRight=”true” />
- <TextView android:id=”@+id/row” android:layout_width=”fill_parent” android:layout_height=”fill_parent” android:padding=”10dp” android:scrollbars=”vertical” android:fadingEdge=”vertical” android:textColor=”@color/notepad_text” android:layout_alignParentLeft=”@+id/rowDate” /> </RelativeLayout>
5. 创建一个新的类(ToDoItemAdapter),使用指定的ToDoItem变量来扩展一个ArrayAdapter。重写getView方法来将ToDoItem对象中的task和date属性指定给第4步创建的layout中的View。
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://dxs376263348.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=import%20java.text.SimpleDateFormat%3B%0Aimport%20android.content.Context%3B%0Aimport%20java.util.*%3B%20%0Aimport%20android.view.*%3B%0A%20import%20android.widget.*%3B%20%0Apublic%20class%20ToDoItemAdapter%20extends%20ArrayAdapter%3CToDoItem%3E%20%7B%20int%20resource%3B%20public%20ToDoItemAdapter(Context%20_context%2Cint%20_resource%2C%20List%3CToDoItem%3E%20_items)%20%7B%20%0Asuper(_context%2C%20_resource%2C%20_items)%3B%20resource%20%3D%20_resource%3B%0A%20%7D%20%0A%20%40Override%20public%20View%20getView(int%20position%2C%20View%20convertView%2C%20%20ViewGroup%20parent)%20%7B%20%0A%20%20LinearLayout%20todoView%3B%20ToDoItem%20item%20%3D%20getItem(position)%3B%20%0A%20%20String%20taskString%20%3D%20item.getTask()%3B%20%0A%20%20Date%20createdDate%20%3D%20item.getCreated()%3B%20%0A%20%20SimpleDateFormat%20sdf%20%3D%20new%20SimpleDateFormat(%E2%80%9Cdd%2FMM%2Fyy%E2%80%9D)%3B%20%0A%20%20String%20dateString%20%3D%20sdf.format(createdDate)%3B%20if%20(convertView%20%3D%3D%20null)%20%7B%20todoView%20%3D%20new%20LinearLayout(getContext())%3B%20%0A%20%20String%20inflater%20%3D%20Context.LAYOUT_INFLATER_SERVICE%3B%20%0A%20%20LayoutInflater%20vi%3B%20vi%20%3D%20(LayoutInflater)getContext().getSystemService(inflater)%3B%20vi.inflate(resource%2C%20todoView%2C%20true)%3B%20%0A%7D%20%0Aelse%20%7B%0A%20todoView%20%3D%20(LinearLayout)%20convertView%3B%20%0A%7D%20%0A%20%20TextView%20dateView%20%3D%20(TextView)todoView.findViewById%20(R.id.rowDate)%3B%20%0A%20TextView%20taskView%20%3D%20(TextView)todoView.findViewById(R.id.row)%3B%20%20%20%20%20%20dateView.setText(dateString)%3B%0A%20%20%20%20taskView.setText(taskString)%3B%0A%20%20%20%20return%20todoView%3B%20%0A%20%20%7D%20%0A%7D%20%0A"></embed>
- import java.text.SimpleDateFormat;
- import android.content.Context;
- import java.util.*;
- import android.view.*;
- import android.widget.*;
- public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { int resource; public ToDoItemAdapter(Context _context,int _resource, List<ToDoItem> _items) {
- super(_context, _resource, _items); resource = _resource;
- }
- @Override public View getView(int position, View convertView, ViewGroup parent) {
- LinearLayout todoView; ToDoItem item = getItem(position);
- String taskString = item.getTask();
- Date createdDate = item.getCreated();
- SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yy”);
- String dateString = sdf.format(createdDate); if (convertView == null) { todoView = new LinearLayout(getContext());
- String inflater = Context.LAYOUT_INFLATER_SERVICE;
- LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, todoView, true);
- }
- else {
- todoView = (LinearLayout) convertView;
- }
- TextView dateView = (TextView)todoView.findViewById (R.id.rowDate);
- TextView taskView = (TextView)todoView.findViewById(R.id.row); dateView.setText(dateString);
- taskView.setText(taskString);
- return todoView;
- }
- }
6. 最后,用ToDoItemAdapter替换ArrayAdapter的定义。
private ToDoItemAdapter aa;
在onCreate中,使用new ToDoItemAdapter来替换ArrayAdapter<String>的实例化。
aa = new ToDoItemAdapter(this, resID, todoItems);
7. 如果你运行Activity,它看起来如图5-4的截图。
分享到:
相关推荐
Android中Adapter的工作原理.pdf 学习资料 复习资料 教学资源
android中ArrayAdapter SimpleAdapter BaseAdapter 的使用
Android自定义adapter的listview代码
如有疑问,欢迎和我交流。博客地址http://blog.csdn.net/footballclub/article/details/43193847,
android gridview adapter 实例 每个getview显示不同的数据
Android之Adapter用法总结
基于Eclipse开发平台,Android中使用ListView和三种适配器(ArrayAdaper,SimpleAdapter,BaseAdapter)实现数据的填充。
Android_Adapter 讲解Android_Adapter 讲解Android_Adapter 讲解Android_Adapter 讲解Android_Adapter 讲解
android recyclerview adapter 照片选择器 给recyclerview 添加adapter适置器进行照片选择,可以对recyclerview进行行数和张数的设置,也可以对已选择的照片进行增减。
Android ListView adapter不同布局,当需要用到ListView叠加嵌套时候可以考虑
ListView与BaseAdapter的配套使用 理解android 中adapter适配的作用 以及ListView的优化方式
这个是我写的一个自定义Adapter适配器,用来绑定数据到ListView上。我写的代码非常简单易懂
该例中包含了常用的Adapter的使用,如baseadapter、simpleAdapter、SimlpeCursorAdapter和ArrayAdapter,例子写在一个工程中的。请注意切换清单文件中启动的Activity。
Android listview与adapter操作和用法
android中adapter整理,包括Baseadapter,Simpleadapter,cursoradapter的详细使用说明
Android 实现适配器中的子控件与Activity通信
android开发Adapter详解,帮助你加深进一步的理解···
本篇文章主要介绍了Android之Adapter用法总结,具有一定的参考价值,有需要的可以了解一下。
This project evolved into module easyadapter Surf Android Standard repository (Documentation in Russian). It contains modules, which is used for developing Android projects by mobile studio Surf. Easy...
本代码深入讲解了Android适配器各种对象的使用,适合初学者学习。