`
yahaitt
  • 浏览: 756518 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论
阅读更多

Adapter介绍

 

Adapter是将数据绑定到UI界面上的桥接类。Adapter负责创建显示每个项目的子View和提供对下层数据的访问。

 

支持Adapter绑定的UI控件必须扩展AdapterView抽象类。创建自己的继承自AdapterView的控件和创建新的Adapter类来绑定它们是可能的。

 

一些Android提供的Adapter介绍

 

在多数情况下,你不需要白手创建自己的AdapterAndroid提供了一系列Adapter来将数据绑定到UI Widget上。

 

因为Android负责提供数据和选择用于显示每个项目的View,所以Adapter能快速地修改要绑定的控件的外观和功能。下面的列表显示了两个最有用和最通用的本地Adapter

 

 ArrayAdapter

ArrayAdapter是一个绑定View到一组对象的通用类。默认情况下,ArrayAdapter绑定每个对象的toString值到在layout中预先定义的TextView控件上。可变通的,构造函数允许你使用更加复杂的layout或者通过重写getView方法来扩展类从而使用TextView的替代物(如ImageView或嵌套的layout)。

 

 SimpleCursorAdapter

SimpleCursorAdapter绑定ViewContent Provider查询返回的游标上。指定一个XML layout定义,然后将数据集中的每一列的值绑定到layout中的一个View上。

 

接下来的章节将深入挖掘这些Adapter类的细节。例子中,提供了绑定数据到ListView上,尽管这个逻辑会和其他一些AdapterView类(如SpinnerGallery)工作的一样。

 

使用Adapter进行数据绑定

 

Adapter应用到继承自AdapterView类上,你需要调用ViewsetAdapter方法,传入一个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,修改ArrayListArrayAdapter变量的类型,储存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>
  1. private ArrayList<ToDoItem> todoItems;  
  2. private ListView myListView;   
  3. private EditText myEditText;   
  4. private ArrayAdapter<ToDoItem> aa;   
  5. @Override public void onCreate(Bundle icicle) {  
  6.  super.onCreate(icicle); // Inflate your view setContentView(R.layout.main); //    
  7.  Get references to UI widgets myListView = (ListView)findViewById(R.id.myListView);  
  8.     myEditText = (EditText)findViewById(R.id.myEditText);   
  9.     todoItems = new ArrayList<ToDoItem>();   
  10.     int resID = R.layout.todolist_item; aa = new ArrayAdapter<ToDoItem>(this, resID, todoItems);   
  11.     myListView.setAdapter(aa);  
  12.  myEditText.setOnKeyListener(new OnKeyListener() {   
  13. public boolean onKey(View v, int keyCode, KeyEvent event) {  
  14.  if (event.getAction() == KeyEvent.ACTION_DOWN)  
  15.    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {   
  16.    ToDoItem newItem; newItem = new ToDoItem(myEditText.getText().toString()); todoItems.add(0, newItem);  
  17.     myEditText.setText(“”);   
  18.     aa.notifyDataSetChanged(); cancelAdd(); return true;   
  19.       }   
  20.     return false;   
  21.     }  
  22.   });  
  23.  registerForContextMenu(myListView);   
  24. }   

 

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>
  1. <?xml version=”1.0” encoding=”utf-8”?>   
  2. <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”>   
  3. <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” />   
  4. <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对象中的taskdate属性指定给第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>
  1. import java.text.SimpleDateFormat;  
  2. import android.content.Context;  
  3. import java.util.*;   
  4. import android.view.*;  
  5.  import android.widget.*;   
  6. public class ToDoItemAdapter extends ArrayAdapter<ToDoItem> { int resource; public ToDoItemAdapter(Context _context,int _resource, List<ToDoItem> _items) {   
  7. super(_context, _resource, _items); resource = _resource;  
  8.  }   
  9.  @Override public View getView(int position, View convertView,  ViewGroup parent) {   
  10.   LinearLayout todoView; ToDoItem item = getItem(position);   
  11.   String taskString = item.getTask();   
  12.   Date createdDate = item.getCreated();   
  13.   SimpleDateFormat sdf = new SimpleDateFormat(“dd/MM/yy”);   
  14.   String dateString = sdf.format(createdDate); if (convertView == null) { todoView = new LinearLayout(getContext());   
  15.   String inflater = Context.LAYOUT_INFLATER_SERVICE;   
  16.   LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, todoView, true);   
  17. }   
  18. else {  
  19.  todoView = (LinearLayout) convertView;   
  20. }   
  21.   TextView dateView = (TextView)todoView.findViewById (R.id.rowDate);   
  22.  TextView taskView = (TextView)todoView.findViewById(R.id.row);      dateView.setText(dateString);  
  23.     taskView.setText(taskString);  
  24.     return todoView;   
  25.   }   
  26. }   
 

6. 最后,用ToDoItemAdapter替换ArrayAdapter的定义。

 

private ToDoItemAdapter aa;

 

onCreate中,使用new ToDoItemAdapter来替换ArrayAdapter<String>的实例化。

 

aa = new ToDoItemAdapter(this, resID, todoItems);

 

7. 如果你运行Activity,它看起来如图5-4的截图。

 

分享到:
评论
2 楼 renfujiang 2011-07-18  
怎么清除呢?
1 楼 renfujiang 2011-07-18  
怎么清除呢?

相关推荐

Global site tag (gtag.js) - Google Analytics