`
ForgetLove
  • 浏览: 23516 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Android Adapter详解

阅读更多
Android Adapter

Adapter是用来帮助填充数据的中间桥梁,比如通过它将数据填充到ListView, GridView, Gallery.android 提供了几种Adapter:ArrayAdapter, BaseAdapter, CursorAdapter, HeaderViewListAdapter, ListAdapter, ResourceCursorAdapter, SimpleAdapter, SimpleCursorAdapter, SpinnerAdapter, WrapperListAdapter.

根据数据来源形式的不同可以选择不同的Adapter,比如数据来源于一个Arraylist 就使用BaseAdapter,SimpleAdapter,而数据来源于通过查询数据库获得Cursor那就使用

如有更多问题想更多讨论此类话题,请加我的群 182503495 攻城狮工会
Adapter应用总结

首先来看一下Adapter的体系结构:

一个Adapter的对象扮演一个桥梁的角色。这个桥梁连接着一个AdapterView和它所包含的数据。Adapter提供了一个通到数据项的途径。Adapter还负责为在数据集里的每个数据生项生成一个View。它有一个重要的方法:

public abstract View getView (int position,View convertView,ViewGroup parent)

。这个方法被setListAdapteradapter)间接地调用。getView 方法的作用是得到一个View,这个view显示数据项里指定位置的数据,你可以或者手动创建一个view或者从一个XML layoutinflate。当这个viewinflated,它的父view(如GridView,ListView等)将要使用默认的layout参数,除非你用inflate(int,android.view.ViewGroup,boolean)方法来指定一个根view并防止附着在根上。

下面分别讲一下它的几个常见的子类:

ListAdapter接口:继承于AdapterListAdapter是一个ListViewlist上的数据之间的桥梁。数据经常来自于一个Cursor,但这不是必须的。ListView能显示任何数据,只要它是被一个ListAdapter包装的。

BaseAdapter抽象类:是一个实现了既能在ListView(实现了ListAdapter接口)Spinner(实现了Spinner接口)里用的Adapter类的一般基类。

ArrayAdapter类:一个管理这样的ListViewListAdapter:这个ListView被一个数组所支持。这个数组可装任意对象。默认状态下,这个类预期能这样:提供的资源id与一个单独的TextView相关联。如果你想用一个更复杂的layout,就要用包含了域id的构造函数。这个域id能够与一个在更大的layout资源里的TextView相关联。它将被在数组里的每个对象的toString()方法所填满。你可以添加通常对象的listsarrays。重写你对象的toString()方法来决定list里哪一个写有数据的text将被显示。如果想用一些其它的不同于TextViewview来显示数组(比如ImageViews),或想有一些除了toString()返回值所填在views里的以外的数据,你就要重写getView(int,View,ViewGroup)方法来返回你想要的View类型。

SimpleAdapter类:一个使静态数据和在XML中定义的Views对应起来的简单adapter。你可以把list上的数据指定为一个Map范型的ArrayListArrayList里的每一个条目对应于list里的一行。Maps包含着每一行的数据。你先要指定一个XML,这个XML定义了用于显示一行的view。你还要指定一个对应关系,这个对应关系是从Mapkeys对应到指定的views。绑定数据到views发生在两个阶段:

如果一个simpleAdapter.ViewBinder是可用的,那么SetViewValue(android.view.View,Object,String)要被调用。如果返回true,那么绑定发生了。如果返回false,那么如下views将被按顺序地尝试:

~实现了CheckableView(如CheckBox),预期的绑定值是boolen

TextView,预期的绑定值是String,并且SetViewText方法被调用

ImageView,预期的绑定值是一个资源的idString。并且SetViewImage方法被调用

如果没有合适的绑定被发现,一个IllegalStateException被抛出。

下面是一个SimpleAdapter的例子:

/*--------------------mail.xml---------------------------*/

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:id="@+id/MyListView">

/*--------------------simple_list_item_2.xml---------------------------*/

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/widget0"

android:layout_width="fill_parent"

android:layout_height="fill_parent">

android:id="@+id/ItemImage"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

android:id="@+id/ItemTitle"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="TextView"

android:layout_x="50px"

android:textSize="15pt">

android:id="@+id/ItemText"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="TextView"

android:layout_x="50px"

android:layout_y="40px">

android:id="@+id/ItemCheck"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_x="270px">

/*--------------------TestUIList.java---------------------------*/

public class TestUIList extends Activity {

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

ListView list = (ListView) findViewById(R.id.MyListView);

ArrayList> lstImageItem = new ArrayList>();

String[] str1 = { "row one", "row two", "row three", "row four" };

String[] str2 = { "第一行", "第二行", "第三行", "第四行" };

for (int i = 0; i < str1.length; i++) {

HashMap map = new HashMap();

map.put("ItemImage", R.drawable.icon);

map.put("ItemTitle", str1[i]);

map.put("ItemText", str2[i]);

lstImageItem.add(map);

}

SimpleAdapter saImageItems = new SimpleAdapter(this,

lstImageItem,

R.layout.simple_list_item_2,

new String[] { "ItemImage", "ItemTitle", "ItemText" },

new int[] { R.id.ItemImage, R.id.ItemTitle, R.id.ItemText });

list.setAdapter(saImageItems);

}

}

如果你的ListView的每一行想实现被点击后有响应事件。最省事发的方法是继承一个ListActivityListActivity是一个这样的Activity:这个Activity能通过绑定到一个像arraycursor这样的数据源来显示一些itemslist,并且当用户选了一个item时,能够暴露事件句柄。

ListActivity拥有一个ListView对象。这个ListView对象能够被绑定到不同的数据源,特别是一个数组或者一个拥有查询结果的CursorListActivity有三种用法,分别是Binding,Screen LayoutRow Layout。下面仅讨论一下Screen Layout

ListActivity有一个默认的layout。这个 layout是由一个在屏幕中央的、单独的、全屏的list构成。然而,如果你想的话,你可以通过在onCreate()里调用setContentView()方法来设置你自己的view layout的方式制定屏幕layout。要这样做,你自己的view必须包含一个id“@android:id/android:list”(或者在代码中有list对象)。

随意地,当你制定这个view是空的时,你能够包含任何类型的view对象来显示。这个list”通知者必须有一个id“android:empty”

注意,最后一定要调用setListAdapter(adapter)方法来把通过Adapter绑定了数据的这个List显示出来。setListAdapter方法间接调用了AdaptergetView方法,其作用是返回你想要的view类型。而且当点击listView里的item时,会根据getView重画这个ListView。例子可参见《Android SDK开发大全》中的资源管理器的例子。

想要实现事件监听,就要重写 protected void onListItemClick(ListView l, View v, int position,long id)方法。

想要把在XML中自定义了一行的view逐行显示在ListActivity中自定义的ListView中,并且在每行动态绑定数据的话,一般要自己写一个MyAdapter类,这个Adapter继承BaseAdapter并且其构造函数中至少有一个List参数来实现动态绑定数据。有两个重要的步骤:

1)重写getView方法,其中一重要步骤就是用items.get(position)方法来获得被传入的数据。其中items是一个List,它被赋了传入的List参数的值。position是这个数据在ListView中的行数。Get返回的是E类型.List中的模板类型。

2)写一个内部类private class ViewHolder。这个内部类只有成员变量,它们就是你想在ListView中的一行里要显示的小View成分。

要想在Adapter中动态传入其它类的数据,就要在构造函数中再增加一个(或更多)List参数。

最后我们给出自己些的MyAdapter配合ListActivity实现监听事件的例子:

/*--------------------MyHome.java-----------------------*/

package com.li.android.myhome;

import java.util.ArrayList;

import java.util.List;

import android.app.AlertDialog;

import android.app.ListActivity;

import android.content.DialogInterface;

import android.os.Bundle;

import android.view.View;

import android.widget.ListView;

public class MyHome extends ListActivity

{

private List items = null;

protected void onCreate(Bundle icicle)

{

super.onCreate(icicle);

setContentView(R.layout.main);

items = new ArrayList();

String[] titles =

{ "默认主题", "主题-A", "主题-B", "中秋佳节", "粉红女郎", "花样年华" };

for (int i = 0; i < titles.length; i++)

{

String title = titles[i];

items.add(title);

}

setListAdapter(new MyAdapter(this, items));

}

@Override

protected void onListItemClick(ListView l, View v, int position,

long id)

{

new AlertDialog.Builder(MyHome.this).setItems(

R.array.items_my_dialog, new DialogInterface.OnClickListener()

{

public void onClick(DialogInterface dialog, int whichcountry)

{

}

})

.show();

}

}

/*--------------------MyAdapter.java-----------------------*/

package com.li.android.myhome;

import java.util.List;

import android.content.Context;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

public class MyAdapter extends BaseAdapter

{

private LayoutInflater mInflater;

private Bitmap icom_theme;

private Bitmap icon_selected32;

private List items;

public MyAdapter(Context context, List it)

{

mInflater = LayoutInflater.from(context);

items = it;

icom_theme = BitmapFactory.decodeResource(context.getResources(),

R.drawable.theme);

icon_selected32 = BitmapFactory.decodeResource(context

.getResources(), R.drawable.selected32);

}

public int getCount()

{

return items.size();

}

public Object getItem(int position)

{

return items.get(position);

}

public long getItemId(int position)

{

return position;

}

public View getView(int position, View convertView, ViewGroup parent)

{

ViewHolder holder;

convertView = mInflater.inflate(R.layout.file_row, null);

holder = new ViewHolder();

holder.text = (TextView) convertView.findViewById(R.id.text);

holder.mTheme = (ImageView) convertView.findViewById(R.id.theme);

holder.mSelected32 = (ImageView) convertView

.findViewById(R.id.selected32);

holder.mTheme.setImageBitmap(icom_theme);

String title = items.get(position);

holder.text.setText(title);

holder.mSelected32.setImageBitmap(icon_selected32);

return convertView;

}

private class ViewHolder

{

TextView text;

ImageView mTheme;

ImageView mSelected32;

}

}

/*--------------------main.xml-----------------------*/

xmlns:android="http://schemas.android.com/apk/res/android"

android:orientation="vertical"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

>

android:id="@android:id/list"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

>

/*-------------------- file_row.xml-----------------------*/

xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/widget0"

android:layout_width="fill_parent"

android:layout_height="fill_parent" >

android:layout_width="wrap_content"

android:layout_height="wrap_content"

>

android:id="@+id/text"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:layout_x="50px"

android:textSize="15pt">

android:id="@+id/selected32"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_x="270px">

/*--------------------string.xml-----------------------*/

Hello World, 仿熊猫

仿熊猫

应用主题

编辑主题

删除主题

dapterAndroid中占据一个重要的角色,它是数据和UIView)之间一个重要的纽带。在常见的View(ListView,GridView)等地方都需要用到Adapter。如图1直观的表达了DataAdapterView三者的关系。


1 Adapter、数据、UI三者关系(PS:此图来自Google I/O

 

一、AndroidAdapter



 

2AndroidAdapter类型层级图

由图2我们可以看到在Android中与Adapter有关的所有接口、类的完整层级图。在我们使用过程中可以根据自己的需求实现接口或者继承类进行一定的扩展。比较常用的有 BaseAdapterArrayAdapterSimpleCursorAdapter等。

·BaseAdapter是一个抽象类,继承它需要实现较多的方法,所以也就具有较高的灵活性;

·ArrayAdapter支持泛型操作,通常需要实现getView方法,特殊情况下(结合数据row id),为了让ui事件相应处理方便点最好重写getItemId

·SimpleCursorAdapter可以适用于简单的纯文字型ListView,它需要Cursor的字段和UIid对应起来。如需要实现更复杂的UI也可以重写其他方法。

二、一个继承BaseAdapter的类的代码段

1:/**

2:* 歌曲列表适配器

3:*

4:* @version 2010-11-24 下午05:13:33

5:* @author Hal

6:*/

7:publicclass AudioListAdapter extends BaseAdapter {

8:

9:private Context mContext;

10:

11:// 歌曲集合

12:private ArrayList<Audio> mAudios;

13:

14:public AudioListAdapter(Context mContext, ArrayList<Audio> mAudios) {

15:this.mContext = mContext;

16:this.mAudios = mAudios;

17:}

18:

19:@Override

20:publicint getCount() {

21:return mAudios != null ? mAudios.size() : 0;

22:}

23:

24:@Override

25:public Object getItem(int position) {

26:if ((mAudios != null && mAudios.size() > 0) && (position >= 0 && position < mAudios.size())) {

27:return mAudios.get(position);

28:}

29:returnnull;

30:}

31:

32:/**

33:* 如果集合中的对象数据来自数据库,建议此方法返回该对象在数据库中的ID

34:*/

35:@Override

36:publiclong getItemId(int position) {

37:if ((mAudios != null && mAudios.size() > 0) && (position >= 0 && position < mAudios.size())) {

38:return mAudios.get(position).getId();

39:}

40:return position;

41:}

42:

43:@Override

44:public View getView(int position, View convertView, ViewGroup parent) {

45://TODO 返回自定的View

46:}
 

  • 大小: 26.6 KB
  • 大小: 54.9 KB
分享到:
评论

相关推荐

    android adapter详解

    android adapter适配器详解

    Android adapter详解

    个人整理的关于adapter的详细讲解,文章图文并茂,从简单到复杂,从原理到实践。让你更好更快的理解adapter。

    Android Adapter详解(2)

    NULL 博文链接:https://18767136122.iteye.com/blog/1995973

    android开发Adapter详解

    android开发Adapter详解,帮助你加深进一步的理解···

    Android listview与adapter详解及实例代码

    本文主要介绍Android listview与adapter的知识详解,这里整理了相关资料及实现代码和实现效果图,有兴趣的小伙伴可以参考下

    Android Adapter里面嵌套ListView实例详解

    主要介绍了Android Adapter里面嵌套ListView实例详解的相关资料,这里提供实例代码并说明如何实现该功能,需要的朋友可以参考下

    Android ListView

    Android ListView 详解,适配器adapter详解 博客地址:http://blog.csdn.net/csdnyuandaimaxuexi/article/details/48808303

    Android基础知识详解

    自定义Adapter来建立复杂的列表项 99 动态添加、删除ListView列表项 102 改变ListView列表项选中状态的背景颜色 102 可展开的列表组件 102 数据的存取 103 SharePreferences 6.1 103 文件的存储6.2 103 SQLite数据库...

    Android学习资料

    收集的一些关于Android的学习...Android之Adapter用法总结,Android中图片的处理,BaseExpandableListAdapter的使用,反编译android app,详解 Android 的 Activity 组件,需要的朋友可以下载查看(直接双击html文件查看即可)

    Android ListView的OnItemClickListener详解

    我们在使用ListView的时候,一般都会为ListView添加一个响应事件android.widget.AdapterView.OnItemClickListener。本文主要在于对OnItemClickListener的position和id参数做详细的解释,我相信有些人在这上面走了些...

    Android RecyclerView网格布局(支持多种分割线)详解(2)

    上篇Android RecyclerView 详解(1)—线性布局 记录了下RecyclerView的使用方法,并且讲述了线性布局列表的使用方法,在此基础上加上了万能分割线,支持颜色分割线和图片分割线,同时支持对分割线设置线宽。 这篇...

    Android ListView适配器(Adapter)优化方法详解

    Android ListView的优化,在做Android项目的时候,在用到ListView 界面及数据显示,这个时候如果资源过大,对项目来说,用户体验肯定是不好的,这里就对如何优化做了详细介绍: Adapter的作用就是ListView界面与数据...

    MultiItem用法与详解-优雅的实现多类型RecyclerView Adapter

    参考 MultiItem用法与详解-优雅的实现多类型RecyclerView Adapter(https://www.jianshu.com/p/7dc7c8201a90),在此感谢作者。我在MyInputDemoActivity中又添加了表单项验证、弹出popwindow的表单项、省市区三级...

    Android SimpleAdapter适配器使用详解

    Android SimpleAdapter使用详解 HolderAdapter背景 Android的AdapterView用的比较多,ListView,GridView,Spinner等,原生的BaseAdapter对ViewHolder没有支持,每次都要,定义内部类,inflater根布局,对item内部...

    简单好用的Adapter---ArrayAdapter详解

    主要介绍了简单好用的Adapter---ArrayAdapter详解,具有一定参考价值,需要的朋友可以了解下。

    android studio 的下拉菜单Spinner使用详解

    Spinner 与 Gallery 都继承了AbsSpinner,AbsSpinner 继承了AdapterView,因此它也表现出AdapterView的特征:只要为AdapterView提供Adapter即可。 1.相关属性 android:dropDownHorizontalOffset:设置列表框的水平...

    android开发教程之自定义属性用法详解

    最近项目中经常需要用到自定义控件,因此自定义属性也是经常要用到的,在此说明一下自定义属性的用法: 自定义属性都存在于/value/attr.xml文件中,以如下格式存在。 代码如下: ”自定义属性名称”&gt; ...

Global site tag (gtag.js) - Google Analytics