Android进阶(十四)Android Adapter详解

  • SimpleCursorAdapter类:SimpleCursorAdapter绑定View到Content Provider查询返回的游标上。指定一个XML layout定义,然后将数据集中的每一列的值绑定到layout中的一个View上。
  • SimpleAdapter类:一个使静态数据和在XML中定义的Views对应起来的简单adapter。你可以把list上的数据指定为一个Map范型的ArrayList。ArrayList里的每一个条目对应于list里的一行。Maps包含着每一行的数据。

你先要指定一个XML,这个XML定义了用于显示一行的view。你还要指定一个对应关系,这个对应关系是从Map的keys对应到指定的views。

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

  1. 实现了Checkable的View(如CheckBox),预期的绑定值是boolen。
  2. TextView,预期的绑定值是String,并且SetViewText方法被调用。
  3. ImageView,预期的绑定值是一个资源的id或String。并且SetViewImage方法被调用。

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

不论是那种适配器模式,也不管是Listview也好还是gridview也好,对他们填充数据,都是分三步走。

第一:创建一个数据填充的对象,可以是ListView, GridView, Gallery。

listView=(ListView) findViewById(R.id.listview_simple); 

第二步:创建一个数据填充器,可以是BaseAdapter、SimpleAdapter,也可以是与数据库相关联的CursorAdapter

例如:SimpleAdapter可以使用系统封装好的,你也可以自己去继承一个Simpleadapter,来重写其中的方法。继承 simpleadapter的好处在于,你可以对listitem中每个单一的控件设置监听事件等等一系列操作。如果用的是系统封装好的就有点爱莫能助了。

直接使用系统封装的:

SimpleAdapter simpleAdapter = new SimpleAdapter(this,data, R.layout.simple_item, new String[] { "name", "info" },  new int[] { R.id.simple_name, R.id.simple_info }); 

重写系统的simpleadpter

public class ListSimpleAdpter extends SimpleAdapter{

  //要使用到的数据源 

  private List<MAP><STRING,object="">> data=new ArrayList<MAP><STRING, object="">>(); 

  //填充数据的资源文件 

  private int resource;

  private String[] from; 

  private Context context;

  public ListSimpleAdpter(Context context, List<MAP><STRING, object="">> data, int resource, String[] from, int[] to) { 

  super(context, data, resource, from, to); 

  this.context=context; 

  this.data=data; 

  this.resource=resource; 

  this.from=from; } 

  //item的总行数

   @Override 

  public int getCount() { 

    return data==null?0:data.size();

  } 

  //item对象 

  @Override 

  public Object getItem(int position) { 

    return position;

  }

  //item的id

  @Override 

  public long getItemId(int position) { 

    return position; 

  } 

//绘制每一个item 

@Override 

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

  	Holder holder = null;

   if(convertView==null) { 

    convertView=LayoutInflater.from(context).inflate(resource, null); 

    holder=new Holder(); 

    holder.imageView=(ImageView) convertView.findViewById(R.id.listitem_pic); 

    holder.title=(TextView) convertView.findViewById(R.id.listitem_title);

    holder.content=(TextView) convertView.findViewById(R.id.listitem_content);

   convertView.setTag(holder); 

  } else { 

    holder=(Holder) convertView.getTag(); 

  } 

  holder.imageView.setImageResource(Integer.parseInt(data.get(position).get(from[0]).toString()));

  holder.title.setText(data.get(position).get(from[1]).toString()); 

  holder.content.setText(data.get(position).get(from[2]).toString()); return convertView;

 }   

  class Holder{ 

    ImageView imageView; 

    TextView title; 

    TextView content;

   } 

}

第三步:将数据填充到对象中去

listView.setAdapter(simpleAdapter); 

这样就完成了数据填充器的数据填充。

下面是一个SimpleAdapter的例子:

/*--------------------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的每一行想实现被点击后有响应事件。最省事的方法是继承一个ListActivity。

ListActivity是一个这样的Activity:这个Activity能通过绑定到一个像array或cursor这样的数据源来显示一些items的list,并且当用户选了一个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方法间接调用了Adapter的getView方法,其作用是返回你想要的view类型。

而且当点击listView里的item时,会根据getView重画这个ListView。想要实现事件监听,就要重写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 应用实战

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

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

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

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



### 文末

从转行到现在,差不多两年的时间,虽不能和大佬相比,但也是学了很多东西。我个人在学习的过程中,习惯简单做做笔记,方便自己复习的时候能够快速理解,现在将自己的笔记分享出来,和大家共同学习。



个人将这段时间所学的知识,分为三个阶段:

第一阶段:HTML&CSS&JavaScript基础

![](https://img-blog.csdnimg.cn/img_convert/3e0d5b0f6a97b823cc1ef22ff1a18191.png)



第二阶段:移动端开发技术

![](https://img-blog.csdnimg.cn/img_convert/fc21db0a800494796dc6408ce1486031.png)

第三阶段:前端常用框架

![](https://img-blog.csdnimg.cn/img_convert/644efd4ddd0f8d43535f1982ec0da6e4.png)



**[开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】](https://bbs.csdn.net/topics/618166371)**

*   推荐学习方式:针对某个知识点,可以先简单过一下我的笔记,如果理解,那是最好,可以帮助快速解决问题;

*   大厂的面试难在,针对一个基础知识点,比如JS的事件循环机制,不会上来就问概念,而是换个角度,从题目入手,看你是否真正掌握。所以对于概念的理解真的很重要。
  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值