前言
第一次用SimpleAdapter向LiveView加数据的时候,觉得使用List<Map>作为数据源怪怪的。
Google这样的设计也可以理解,因为使用Map的话,数据取值的时候确实比使用对象时更快,因为如果设计成自定义对象,取值时必定使用到反射,对移动设备来讲,使用反射的代价我想是比较高的。
另外好在Android是开源的,不然跟本无法重写这类对象,从而达到我们想要的效果。
下面我们使用反射机制来实现对自定义对象的支持。声明:本人绝对不会使用这种自定义对象的。因为反射的代价太大,这个重写只作研究之用。
下面代码与原SimpleAdapter不同的地方都使用了注释。
package hxf.Adapter;
import hxf.Tools.Reflect;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
public class ObjectSimpleAdapter<T> extends SimpleAdapter{
private List<T> mData;{//把List<Map>转换成泛型
private int[] mTo;
private String[] mFrom;
private ViewBinder mViewBinder;
private final WeakHashMap<View, View[]> mHolders = new WeakHashMap<View, View[]>();
private int mResource;
private LayoutInflater mInflater;
public ObjectSimpleAdapter(Context context, ArrayList<T> data,
int resource, String[] from, int[] to) {
super(context, null, 0, null, null);//这个地方只传个context就好了,因为其他已经无用了。
mData = data;
mResource = resource;
mFrom = from;
mTo = to;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public int getCount() {//必须重写的方法(ListView会调用的),照抄原码
return mData.size();
}
@Override
public Object getItem(int position) {{//必须重写的方法,(ListView会调用的),照抄原码
return mData.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {{{//必须重写的方法,照抄原码
return createViewFromResource(position, convertView, parent, mResource);
}
private View createViewFromResource(int position, View convertView,
ViewGroup parent, int resource) {{{//必须重写的方法,照抄原码,方法名可以随便写,只要getView调用就好了。
View v = convertView;
if (v == null)
{
v = mInflater.inflate(resource, parent, false);
final int[] to = mTo;
final int count = to.length;
final View[] holder = new View[count];
for (int i = 0; i < count; i++)
holder[i] = v.findViewById(to[i]);
mHolders.put(v, holder);
}
bindView(position, v);
return v;
}
private void bindView(int position, View view) {
final Object dataSet = mData.get(position);
if (dataSet == null)
return;
final ViewBinder binder = mViewBinder;
final View[] holder = mHolders.get(view);
final String[] from = mFrom;
final int[] to = mTo;
final int count = to.length;
for (int i = 0; i < count; i++) {
final View v = holder[i];
if (v != null) {
final Object data = Reflect.ref(dataSet, from[i]);//关键的地方,使用反射设置值
String text = data == 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
throw new IllegalStateException(v.getClass().getName() +
" should be bound to a Boolean, not a " + data.getClass());
else if (v instanceof TextView)
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");
}
}
}
}
}
//反射类。
public class Reflect {
public static Object ref(Object obj, String fieldname)
{
try
{
String[] fieldarray = fieldname.split("\\.");
if (fieldarray.length > 1)
return getValue(obj, fieldname);
int length = fieldarray.length;
Object objtemp = obj;
for(int i = 0; i < length; i++)
{
objtemp = getValue(objtemp, fieldarray[i]);
if (i == length - 1 || objtemp == null)
return objtemp;
}
}
catch (Exception E)
{
System.out.println(E.getMessage());
}
return null;
}
@SuppressWarnings("unchecked")
private static Object getValue(Object obj, String fieldname)
{
Class cls = obj.getClass();
Object returnobj = null;
try{
Field field = cls.getField(fieldname);
returnobj = field.get(obj);
}catch (Exception E){}
try{
Method method = cls.getMethod(fieldname);
returnobj = method.invoke(obj);
}catch (Exception E){}
return returnobj;
}
}
欢迎大家加Q讨论:87648714
分享到:
相关推荐
此外,`SimpleAdapter` 虽然简单易用,但它不支持复杂的视图绑定和数据操作,如果需要更高级的功能,例如数据过滤、长按事件、自定义视图等,可能需要使用 `BaseAdapter` 或 `RecyclerView.Adapter` 进行自定义开发...
`ListActivity`的使用大大减少了代码量,使得开发者可以更专注于数据的处理和展示,而不是布局的细节。 `SimpleAdapter`是Android SDK提供的一种适配器,用于将数据源(如数组或列表)映射到`ListView`的项目。它...
为了提高性能,我们应该重写Adapter的`getView()`方法,并使用convertView参数来复用已有的视图对象。此外,还可以使用ViewHolder设计模式,避免在每次创建列表项时查找视图,从而减少不必要的查找操作。 总之,...
ArrayAdapter适合简单的数据绑定,BaseAdapter提供了更大的灵活性,SimpleAdapter简化了Map数据源的绑定,而SimpleCursorAdapter则专为SQLite数据库设计。开发者可以根据实际需求选择合适的适配器,提高代码的可读性...
1. 数据结构:ArrayAdapter直接使用List,而SimpleAdapter使用Map,使得SimpleAdapter在处理复杂数据模型时更方便。 2. 自定义程度:ArrayAdapter需要重写`getView()`进行自定义,而SimpleAdapter通过预定义的layout...
如果需要更复杂的视图交互或定制化行为,可能需要使用`BaseAdapter`或`ArrayAdapter`并重写其部分方法。 总结来说,`SimpleAdapter`是Android开发中快速创建ListView的一种工具,它通过简化数据绑定过程,帮助...
在安卓开发中,`SimpleAdapter` 是一个非常实用的类,它用于将数据集与 `ListView` 或其他可滚动视图进行绑定。本教程将深入探讨 `SimpleAdapter` 的使用,以及如何在 Android 应用中实现列表适配。 首先,`...
这时可以继承SimpleAdapter,重写`getView()`方法,以自定义每一项的显示效果。 **4. 网格布局与GridView:** 如果希望数据以网格形式展示,可以考虑使用GridView,它同样支持使用Adapter。网格布局可以通过设置`...
SimpleAdapter相比ArrayAdapter更灵活,它允许我们用Map来存储每一条数据,每个Map代表ListView的一行。SimpleAdapter的主要特性有: 1. **数据结构**:数据源是一个List, ?>>,每个Map的键值对对应一个视图项的...
总结,ArrayAdapter适用于简单的数据绑定,SimpleCursorAdapter适用于SQLite数据库,而SimpleAdapter则适用于非数据库的Map数据结构。理解并灵活运用这三种Adapter,能够帮助开发者高效地利用ListView展示数据。
在Android开发中,ListView是常用的数据展示控件,而SimpleAdapter是用于将数据绑定到ListView的一种简单方式。然而,由于其默认实现的性能问题,可能导致列表滚动时出现卡顿,尤其是在处理大量数据时。本篇文章将...
ListActivity是Android提供的一种专门用来展示列表的Activity,而SimpleAdapter则是将数据绑定到ListView的简单方式。现在我们详细讲解如何实现这个过程。 首先,我们从一个Activity(我们称之为源Activity)启动另...
面向对象编程是软件开发中的一个核心概念,它允许我们通过模拟真实世界中的对象和它们之间的交互来设计和实现复杂的系统。在Android开发中,ListView是一个关键的组件,它用于显示可滚动的一系列数据项,经常在应用...
Adapter有多种类型,如ArrayAdapter、SimpleAdapter等,开发者可以根据需求选择或自定义Adapter。 3. **传递对象到Adapter** - 在Android中,通常我们会创建一个继承自BaseAdapter的自定义Adapter,然后在Adapter...
在"ListView通过adapter传递对象"的场景下,我们通常使用的是BaseAdapter,因为它提供了更大的灵活性。以下是使用BaseAdapter的基本步骤: 1. **创建数据模型类**:定义一个Java类,表示ListView要展示的对象。例如...
Android提供了多种内置Adapter,如ArrayAdapter、SimpleAdapter等,但通常我们需要自定义Adapter来满足特定需求,如设置点击事件。 3. **点击事件监听**: 在ListView中,我们通常使用OnItemClickListener来监听Item...
- ViewPager支持模拟物理惯性的滑动效果,可以通过调整`ViewPager#setPageTransformer`中的参数,如`true`表示开启,使滑动更自然流畅。 9. **预加载策略**: - 通过`ViewPager#setOffscreenPageLimit(int limit)...
它需要实现四个关键方法:getCount()返回数据集的大小,getItem()获取指定位置的数据对象,getItemId()返回对应位置的ID,以及getView()方法,用于创建和填充每个列表项的视图。在自定义BaseAdapter时,通常需要重写...
如果需要更复杂的UI效果,可以通过重写父类方法来自定义行为。 总结来说,Android中的Adapter机制为开发者提供了强大的数据展示能力。BaseAdapter提供最大的灵活性,适合需要定制复杂视图的场景;ArrayAdapter简洁...