`
djking
  • 浏览: 8797 次
  • 性别: Icon_minigender_1
  • 来自: 广州
最近访客 更多访客>>
社区版块
存档分类
最新评论

重写SimpleAdapter, 使它更而向对象。

阅读更多
前言
第一次用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
分享到:
评论

相关推荐

    安卓Android源码——(列表SimpleAdapter适配).rar

    此外,`SimpleAdapter` 虽然简单易用,但它不支持复杂的视图绑定和数据操作,如果需要更高级的功能,例如数据过滤、长按事件、自定义视图等,可能需要使用 `BaseAdapter` 或 `RecyclerView.Adapter` 进行自定义开发...

    本示例演示ListActivity、SimpleAdapter()方法的用法

    `ListActivity`的使用大大减少了代码量,使得开发者可以更专注于数据的处理和展示,而不是布局的细节。 `SimpleAdapter`是Android SDK提供的一种适配器,用于将数据源(如数组或列表)映射到`ListView`的项目。它...

    那些复杂的列表总要弄个清楚——(二)用SimpleAdapter做适配器

    为了提高性能,我们应该重写Adapter的`getView()`方法,并使用convertView参数来复用已有的视图对象。此外,还可以使用ViewHolder设计模式,避免在每次创建列表项时查找视图,从而减少不必要的查找操作。 总之,...

    ListView 与ArrayAdapter,BaseAdapter,SimpleAdapter,SimpleCursorAdapter配合使用实例。

    ArrayAdapter适合简单的数据绑定,BaseAdapter提供了更大的灵活性,SimpleAdapter简化了Map数据源的绑定,而SimpleCursorAdapter则专为SQLite数据库设计。开发者可以根据实际需求选择合适的适配器,提高代码的可读性...

    Android之ListView<3>ArrayAdapter,SimpleAdapter

    1. 数据结构:ArrayAdapter直接使用List,而SimpleAdapter使用Map,使得SimpleAdapter在处理复杂数据模型时更方便。 2. 自定义程度:ArrayAdapter需要重写`getView()`进行自定义,而SimpleAdapter通过预定义的layout...

    Android应用源码之(列表之SimpleAdapter适配).zip

    如果需要更复杂的视图交互或定制化行为,可能需要使用`BaseAdapter`或`ArrayAdapter`并重写其部分方法。 总结来说,`SimpleAdapter`是Android开发中快速创建ListView的一种工具,它通过简化数据绑定过程,帮助...

    安卓Android源码——(列表SimpleAdapter适配).zip

    在安卓开发中,`SimpleAdapter` 是一个非常实用的类,它用于将数据集与 `ListView` 或其他可滚动视图进行绑定。本教程将深入探讨 `SimpleAdapter` 的使用,以及如何在 Android 应用中实现列表适配。 首先,`...

    android ListViewSimpleAdapter

    这时可以继承SimpleAdapter,重写`getView()`方法,以自定义每一项的显示效果。 **4. 网格布局与GridView:** 如果希望数据以网格形式展示,可以考虑使用GridView,它同样支持使用Adapter。网格布局可以通过设置`...

    Android中ListView常用的两种适配器ArrayAdapter和SimpleAdapter使用

    SimpleAdapter相比ArrayAdapter更灵活,它允许我们用Map来存储每一条数据,每个Map代表ListView的一行。SimpleAdapter的主要特性有: 1. **数据结构**:数据源是一个List, ?&gt;&gt;,每个Map的键值对对应一个视图项的...

    android ListView及ArrayAdapter,SimpleCursorAdapter,SimpleAdapter用法示例

    总结,ArrayAdapter适用于简单的数据绑定,SimpleCursorAdapter适用于SQLite数据库,而SimpleAdapter则适用于非数据库的Map数据结构。理解并灵活运用这三种Adapter,能够帮助开发者高效地利用ListView展示数据。

    优化SimpleAdapter适配器加载效率的方法

    在Android开发中,ListView是常用的数据展示控件,而SimpleAdapter是用于将数据绑定到ListView的一种简单方式。然而,由于其默认实现的性能问题,可能导致列表滚动时出现卡顿,尤其是在处理大量数据时。本篇文章将...

    android 从activity用intent跳转到listactivity并在其中用simpleadapter在listview中显示数据列

    ListActivity是Android提供的一种专门用来展示列表的Activity,而SimpleAdapter则是将数据绑定到ListView的简单方式。现在我们详细讲解如何实现这个过程。 首先,我们从一个Activity(我们称之为源Activity)启动另...

    理解面向对象的listView

    面向对象编程是软件开发中的一个核心概念,它允许我们通过模拟真实世界中的对象和它们之间的交互来设计和实现复杂的系统。在Android开发中,ListView是一个关键的组件,它用于显示可滚动的一系列数据项,经常在应用...

    安卓listview相关相关-ListView通过adapter传递对象.rar

    Adapter有多种类型,如ArrayAdapter、SimpleAdapter等,开发者可以根据需求选择或自定义Adapter。 3. **传递对象到Adapter** - 在Android中,通常我们会创建一个继承自BaseAdapter的自定义Adapter,然后在Adapter...

    ListView 通过adapter传递对象

    在"ListView通过adapter传递对象"的场景下,我们通常使用的是BaseAdapter,因为它提供了更大的灵活性。以下是使用BaseAdapter的基本步骤: 1. **创建数据模型类**:定义一个Java类,表示ListView要展示的对象。例如...

    listView Item 点击文字跟着变色

    Android提供了多种内置Adapter,如ArrayAdapter、SimpleAdapter等,但通常我们需要自定义Adapter来满足特定需求,如设置点击事件。 3. **点击事件监听**: 在ListView中,我们通常使用OnItemClickListener来监听Item...

    android源码-ViewPager实现微信页面切换效果

    - ViewPager支持模拟物理惯性的滑动效果,可以通过调整`ViewPager#setPageTransformer`中的参数,如`true`表示开启,使滑动更自然流畅。 9. **预加载策略**: - 通过`ViewPager#setOffscreenPageLimit(int limit)...

    android 使用之adapter大全

    它需要实现四个关键方法:getCount()返回数据集的大小,getItem()获取指定位置的数据对象,getItemId()返回对应位置的ID,以及getView()方法,用于创建和填充每个列表项的视图。在自定义BaseAdapter时,通常需要重写...

    adapter.doc

    如果需要更复杂的UI效果,可以通过重写父类方法来自定义行为。 总结来说,Android中的Adapter机制为开发者提供了强大的数据展示能力。BaseAdapter提供最大的灵活性,适合需要定制复杂视图的场景;ArrayAdapter简洁...

Global site tag (gtag.js) - Google Analytics