相似相通

最近一直在养病,没怎么写博客了,实在很抱歉,躺在床上,翻着床头的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);

                            }

                        }

                    }

                }

            }

        }

 

你可能感兴趣的:(相似相通)