最近一直在养病,没怎么写博客了,实在很抱歉,躺在床上,翻着床头的Android开发书籍,仔细品味书的味道。

当看到ListView和GridView的时候,立刻对这两个产生了浓厚的兴趣,相信在Android的世界中,这两个控件有着重要的角色。

这两个控件的用法其实也很类似,往往都是定义一个adapter,然后重写一些方法,重要的方法就是getView那个,在getView中经常采用下面的流程

1,动态加载一个布局页面,这个布局页面相当于ListView和GridView中的一个Item

2,分别获取充当Item的这个View,然后给里面填充东西,将数据按照指定的格式显示。

大概就是这个流程。

有木有发现这个和WPF中的数据模板有点类似,关于数据模板可以在我的博客中寻找相关内容。

在这里,我们看下一个自定义的GridView:

 

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android"  
    android:id="@+id/gridview"
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"
    android:columnWidth="90dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    />

Item的布局文件

<?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="vertical"
     android:layout_marginTop="5dp"
     >
 <ImageView android:id="@+id/image" android:layout_width="80dip"
  android:layout_height="80dip" android:layout_gravity="center_horizontal">
 </ImageView>
 <TextView android:id="@+id/title" android:layout_width="wrap_content"
      android:layout_height="wrap_content" android:layout_gravity="left"
      android:textSize="16dip"
      android:gravity="left">
 </TextView>

 <TextView android:id="@+id/description" android:layout_width="wrap_content"
  android:layout_height="wrap_content" android:layout_gravity="left"
  android:textColor="#938192"
  android:textSize="13dip"
  android:gravity="left"
  >
 </TextView>
</LinearLayout>
Adapter的写法

import
java.util.ArrayList; import java.util.List; import android.content.Context; 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 GridItemAdapter extends BaseAdapter { private LayoutInflater inflater; private List<GridItem> gridItemList; public GridItemAdapter(String[] titles, int[] images,String[] description, Context context) { super(); gridItemList = new ArrayList<GridItem>(); inflater = LayoutInflater.from(context); for (int i = 0; i < images.length; i++) { GridItem picture = new GridItem(titles[i], images[i],description[i]); gridItemList.add(picture); } } @Override public int getCount( ) { if (null != gridItemList) { return gridItemList.size(); } else { return 0; } } @Override public Object getItem( int position ) { return gridItemList.get(position); } @Override public long getItemId( int position ) { return position; } @Override public View getView( int position, View convertView, ViewGroup parent ) { ViewHolder viewHolder; if (convertView == null) { convertView = inflater.inflate(R.layout.grid_item, null); viewHolder = new ViewHolder(); viewHolder.title = (TextView) convertView.findViewById(R.id.title); viewHolder.image = (ImageView) convertView.findViewById(R.id.image); viewHolder.time = (TextView) convertView.findViewById(R.id.description); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } viewHolder.title.setText(gridItemList.get(position).getTitle()); viewHolder.time.setText(gridItemList.get(position).getTime()); viewHolder.image.setImageResource(gridItemList.get(position).getImageId()); return convertView; }

 

 

 

 

现在的开发,有很多框架可以进行选择,这些开发框架简化了很多常用的代码,尤其是注解或者Atrribute的使用,追根到底,这些都是通过反射来完成的,在程序运行的时候

调用这些框架里面的一些方法,这些方法内部使用反射动态识别一些信息,然后将这些信息动态附加到一些操作中,如何动态识别呢?

通过XML的配置,或者注解,说得简单的一些就是元数据信息,根据这些元数据信息进行操作。

配置之后的信息,又如何被识别出来呢?

这需要一个解析操作,这个解析操作中使用了大量的反射来进行的。

我们来看下Xutils这个里面的一个方法的源码:

 private static void injectObject(Object handler, ViewFinder finder) {

        Class<?> handlerType = handler.getClass();

        // inject ContentView
        ContentView contentView = handlerType.getAnnotation(ContentView.class);
        if (contentView != null) {
            try {
                Method setContentViewMethod = handlerType.getMethod("setContentView", int.class);
                setContentViewMethod.invoke(handler, contentView.value());
            } catch (Throwable e) {
                LogUtils.e(e.getMessage(), e);
            }
        }

        // inject view
        Field[] fields = handlerType.getDeclaredFields();
        if (fields != null && fields.length > 0) {
            for (Field field : fields) {
                ViewInject viewInject = field.getAnnotation(ViewInject.class);
                if (viewInject != null) {
                    try {
                        View view = finder.findViewById(viewInject.value(), viewInject.parentId());
                        if (view != null) {
                            field.setAccessible(true);
                            field.set(handler, view);
                        }
                    } catch (Throwable e) {
                        LogUtils.e(e.getMessage(), e);
                    }
                } else {
                    ResInject resInject = field.getAnnotation(ResInject.class);
                    if (resInject != null) {
                        try {
                            Object res = ResLoader.loadRes(
                                    resInject.type(), finder.getContext(), resInject.id());
                            if (res != null) {
                                field.setAccessible(true);
                                field.set(handler, res);
                            }
                        } catch (Throwable e) {
                            LogUtils.e(e.getMessage(), e);
                        }
                    } else {
                        PreferenceInject preferenceInject = field.getAnnotation(PreferenceInject.class);
                        if (preferenceInject != null) {
                            try {
                                Preference preference = finder.findPreference(preferenceInject.value());
                                if (preference != null) {
                                    field.setAccessible(true);
                                    field.set(handler, preference);
                                }
                            } catch (Throwable e) {
                                LogUtils.e(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }

        // inject event
        Method[] methods = handlerType.getDeclaredMethods();
        if (methods != null && methods.length > 0) {
            for (Method method : methods) {
                Annotation[] annotations = method.getDeclaredAnnotations();
                if (annotations != null && annotations.length > 0) {
                    for (Annotation annotation : annotations) {
                        Class<?> annType = annotation.annotationType();
                        if (annType.getAnnotation(EventBase.class) != null) {
                            method.setAccessible(true);
                            try {
                                // ProGuard锛?keep class * extends java.lang.annotation.Annotation { *; }
                                Method valueMethod = annType.getDeclaredMethod("value");
                                Method parentIdMethod = null;
                                try {
                                    parentIdMethod = annType.getDeclaredMethod("parentId");
                                } catch (Throwable e) {
                                }
                                Object values = valueMethod.invoke(annotation);
                                Object parentIds = parentIdMethod == null ? null : parentIdMethod.invoke(annotation);
                                int parentIdsLen = parentIds == null ? 0 : Array.getLength(parentIds);
                                int len = Array.getLength(values);
                                for (int i = 0; i < len; i++) {
                                    ViewInjectInfo info = new ViewInjectInfo();
                                    info.value = Array.get(values, i);
                                    info.parentId = parentIdsLen > i ? (Integer) Array.get(parentIds, i) : 0;
                                    EventListenerManager.addEventMethod(finder, info, annotation, handler, method);
                                }
                            } catch (Throwable e) {
                                LogUtils.e(e.getMessage(), e);
                            }
                        }
                    }
                }
            }
        }

 

posted on 2015-02-12 11:09  醉意人间  阅读(228)  评论(0编辑  收藏  举报