zoukankan      html  css  js  c++  java
  • 相似相通

    最近一直在养病,没怎么写博客了,实在很抱歉,躺在床上,翻着床头的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);
                                }
                            }
                        }
                    }
                }
            }
  • 相关阅读:
    Android 自定义View修炼-Android 实现自定义的卫星式菜单(弧形菜单)View
    Android中SurfaceView的使用详解
    Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
    Android 自定义View修炼-实现自定义圆形、圆角和椭圆ImageView(使用Xfermode图形渲染方法)
    Android 自定义View修炼-Android实现圆形、圆角和椭圆自定义图片View(使用BitmapShader图形渲染方法)
    框架 Spring Boot 技术入门到整合 8-1 Springboot整合Mybatis-使用generatorConfig生成mapper以及pojo
    框架 Spring Boot 技术入门到整合 7-3 Springboot配置全局的异常捕获 -同时兼容web和ajax
    框架 Spring Boot 技术入门到整合 7-2 Springboot配置全局的异常捕获 -ajax形式
    框架 Spring Boot 技术入门到整合 7-1 Springboot配置全局的异常捕获 -web页面跳转
    框架 Spring Boot 技术入门到整合 6-3 thymeleaf 常用标签的使用方法
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/4287563.html
Copyright © 2011-2022 走看看