自定义SimpleAdapter

2024-04-06 22:38
文章标签 自定义 simpleadapter

本文主要是介绍自定义SimpleAdapter,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SimpleAdapter,跟名字一样,一个简单的适配器,既为简单,就只是被设计来做简单的应用的,比如静态数据的绑定,不过仍然有自定义的空间,比如说在每一个ListItem中加一个按钮并添加响应事件.首先还是先看一下SimpleAdapter的定义吧,直接翻译下SDK doc 吧:
  这是一个简单的适配器,可以将静态数据映射到XML文件中定义好的视图。你可以指定由Map组成的List(比如ArrayList)类型的数据。在ArrayList中的每个条目对应List中的一行。Maps包含每一行的数据。你可以指定一个XML布局以指定每一行的视图,根据Map中的数据映射关键字到指定的视图。绑定数据到视图分两个阶段,首先,如果设置了SimpleAdapter.ViewBinder,那么这个设置的ViewBinder的setViewValue(android.view.View, Object, String)将被调用。如果setViewValue的返回值是true,则表示绑定已经完成,将不再调用系统默认的绑定实现。如果返回值为false,视图将按以下顺序绑定数据:
  • 如果View实现了Checkable(例如CheckBox),期望绑定值是一个布尔类型。
  • TextView.期望绑定值是一个字符串类型,通过调用setViewText(TextView, String)绑定。
  • ImageView,期望绑定值是一个资源id或者一个字符串,通过调用setViewImage(ImageView, int) 或 setViewImage(ImageView, String)绑定数据。
  如果没有一个合适的绑定发生将会抛出IllegalStateException。

   先看一下构造函数:

  

public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

参数

  context  SimpleAdapter关联的View的运行环境

  data    一个Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应该包含所有在from参数中指定的键

  resource   一个定义列表项的布局文件的资源ID。布局文件将至少应包含那些在to中定义了的ID

  from         一个将被添加到Map映射上的键名

  to     将绑定数据的视图的ID,跟from参数对应,这些应该全是TextView

  举个例子:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView lv = (ListView) findViewById(R.id.listView1);
String[] from = { "Text", "Button" };
int[] to = { R.id.text, R.id.button };
List<Map<String, ?>> list = new ArrayList<Map<String, ?>>();
for (int i = 0; i < 10; i++) {
Map<String, String> m = new HashMap<String, String>();
m.put("Text", "Text" + i);
m.put("Button", "Button" + i);
list.add(m);
}
SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.listitem, from, to);
lv.setAdapter(adapter);
}

listitem.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" >

<TextView android:layout_width="wrap_content" android:id="@+id/text" android:layout_height="wrap_content" android:layout_weight="1" />

<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" />

</LinearLayout>


  ListView中的每一项都包含一个TextView跟一个Button,在SimpleAdapter的构造函数中,我们指定了要绑定的数据:list, list是一个由Map组成的ArrayList, Map的作用就是连同后面的from, to参数定义数据是如何绑定的,在上面的例子中

String[] from = { "Text", "Button" };
int[] to = { R.id.text, R.id.button };

  而在for循环中每个map都put进了两个键值对,键名跟from中定义的一一对应,这就表示对于ListView中的每一项,依次寻找在to参数中定义的资源ID,根据这个资源ID在to参数数组中的位置,找到from参数中对应位置的值,以这个值为键,在list中的相应项(一个Map)中以这个值为键取出这个键对应的值绑定到这个资源ID对应的视图中.

  在上面的例子中每一个ListItem都包含一个TextView与一个Button,但程序运行起来后会发现,按钮可以点击,而ListItem却无法点击,而且没有对每一个Button关联响应事件,ListItem无法点击是因为按钮抢占了ListItem的焦点,在listitem.xml而已文件中对LinearLayout加上一个属性就可解决问题:

    android:descendantFocusability="blocksDescendants"

  下面的问题就是Button的响应事件了.

  我的们下SimpleAdaper的源码会发现,数据的绑定是能过一个叫bindView的函数实现的

   private void bindView(int position, View view) {
final Map dataSet = mData.get(position);
if (dataSet == null) {
return;
}

final ViewBinder binder = mViewBinder;
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;

for (int i = 0; i < count; i++) {
final View v = view.findViewById(to[i]);
if (v != null) {
final Object data = http://www.cnblogs.com/angeldevil/archive/2012/04/05/dataSet.get(from[i]);
String text = data =http://www.cnblogs.com/angeldevil/archive/2012/04/05/= null ? "" : data.toString();
if (text == null) {
text = "";
}

boolean bound = false;
if (binder != null) {
bound = binder.setViewValue(v, data, text);
}

if (!bound) {
if (v instanceof Checkable) {
if (data instanceof Boolean) {
((Checkable) v).setChecked((Boolean) data);
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text);
} else {
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " +
(data =http://www.cnblogs.com/angeldevil/archive/2012/04/05/= null ? "<unknown type>" : data.getClass()));
}
} else if (v instanceof TextView) {
// Note: keep the instanceof TextView check at the bottom of these // ifs since a lot of views are TextViews (e.g. CheckBoxes). setViewText((TextView) v, text);
} else if (v instanceof ImageView) {
if (data instanceof Integer) {
setViewImage((ImageView) v, (Integer) data);
} else {
setViewImage((ImageView) v, text);
}
} else {
throw new IllegalStateException(v.getClass().getName() + " is not a " +
" view that can be bounds by this SimpleAdapter");
}
}
}
}
}

  其流程大致是,首先检查SimpleAdapter有没有指定SimpleAdapter.ViewBinder,如果指定了就调用其setViewValue方法, SimpleAdapter.ViewBinder是一个接口,也只有这一个方法,如果ViewBinder返回true表示我们已经完成了对这个View的数据绑定,就不再调用系统默认的实现,当然我们也可以设置一个ViewBinder添加一些功能后通过返回false再让系统绑定数据,比如对按钮添加响应事件,而按钮上的文字由默认实现绑定.通过看bindView的实现就可以明白开始时所说的绑定顺序了:Checkable,TextView,ImageView.

  我们对ListItem的自定义是通过对SimpleAdapter设置ViewBinder来实现的

        SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {

@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
if (view instanceof Button) {
final View button = view;
// button.setBackgroundDrawable(getResources().getDrawable(R.drawable.ic_launcher)); view.setOnClickListener(new OnClickListener() {
LinearLayout listItem = (LinearLayout) button.getParent();
TextView tv = (TextView) listItem.findViewById(R.id.text);

@Override
public void onClick(View v) {
Toast.makeText(AdapterDemoActivity.this, tv.getText(), Toast.LENGTH_SHORT).show();
}
});
return false;
}
return false;
}
};
adapter.setViewBinder(binder);

  系统对每一个view调用binder的setViewValue(此例中是R.id.text和R.id.button,一个TextView与一个Button),我们首先检测这个view是不是一个Button,如果是的话就关联点击事件,可能通过getParent()函数取得parentView以找到这个view的兄弟view,比如这个例子中的实现就是点击Button后输出这个Button所在的ListItem中的TextView上的文字.

  在setViewValue中可以完全自定义我们的实现,比如在Button后加一个TextView,当然可以加任何View,但这样做没任何意义,当你需要这样做时你不需要用SimpleAdater而应该用BaseAdapter:

        SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() {

@Override
public boolean setViewValue(View view, Object data, String textRepresentation) {
if (view instanceof Button) {
final View button = view;
LinearLayout listItem = (LinearLayout) button.getParent();
TextView textView = new TextView(AdapterDemoActivity.this);
textView.setText("AA");
listItem.addView(textView,new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
return false;
}
return false;
}
};
adapter.setViewBinder(binder);



 



这篇关于自定义SimpleAdapter的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/881007

相关文章

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

SpringBoot自定义注解如何解决公共字段填充问题

《SpringBoot自定义注解如何解决公共字段填充问题》本文介绍了在系统开发中,如何使用AOP切面编程实现公共字段自动填充的功能,从而简化代码,通过自定义注解和切面类,可以统一处理创建时间和修改时间... 目录1.1 问题分析1.2 实现思路1.3 代码开发1.3.1 步骤一1.3.2 步骤二1.3.3

dubbo3 filter(过滤器)如何自定义过滤器

《dubbo3filter(过滤器)如何自定义过滤器》dubbo3filter(过滤器)类似于javaweb中的filter和springmvc中的intercaptor,用于在请求发送前或到达前进... 目录dubbo3 filter(过滤器)简介dubbo 过滤器运行时机自定义 filter第一种 @A

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06