Android 中的 adapter

系统 1605 0

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和SimpleCursorAdapter例子

 

 

    使用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 对象。

     

     

private ArrayList<ToDoItem> todoItems; private ListView myListView; private EditText myEditText; private ArrayAdapter<ToDoItem> aa; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); // Inflate your view setContentView(R.layout.main); // 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 所示。

 

Android 中的 adapter

5-3

 

4. 现在,你可以创建一个自定义的 layout 来显示每一个 to-do 项目。修改在第 4 章中创建的自定义 layout ,包含另外一个 TextView ,它将用于显示每个 to-do 项目的创建日期。

<?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

 

      
    
     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

5-4

 

使用SimpleCursorAdapter

 

SimpleCursorAdapter 允许你绑定一个游标的列到 ListView 上,并使用自定义的 layout 显示每个项目。

 

SimpleCursorAdapter 的创建,需要传入当前的上下文、一个 layout 资源,一个游标和两个数组:一个包含使用的列的名字,另一个(相同大小)数组包含 View 中的资源 ID ,用于显示相应列的数据值。

 

下面的框架代码显示了如何构造一个 SimpleCursorAdapter 来显示联系人信息:

  String uriString = “content://contacts/people/”; Cursor myCursor = managedQuery(Uri.parse(uriString), null, null, null, null); String[] fromColumns = new String[] { People.NUMBER, eople.NAME }; int[] toLayoutIDs = new int[] { R.id.nameTextView, R.id.numberTextView }; SimpleCursorAdapter myAdapter; myAdapter = new SimpleCursorAdapter(this,R.layout.simplecursorlayout,myCursor,fromColumns,toLayoutIDs)

    
      

 

 

SimpleCursorAdapter 在本章前面的创建选择联系人的例子中使用过。你将在第 6 章学习到更多关于 Content Provider Cursor 的内容,那里你也将找到更多 SimpleCursorAdapter 的例子。

Android 中的 adapter


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论