相似相通

简介: 最近一直在养病,没怎么写博客了,实在很抱歉,躺在床上,翻着床头的Android开发书籍,仔细品味书的味道。 当看到ListView和GridView的时候,立刻对这两个产生了浓厚的兴趣,相信在Android的世界中,这两个控件有着重要的角色。

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

 

相关文章
|
2天前
|
存储 运维 安全
云上金融量化策略回测方案与最佳实践
2024年11月29日,阿里云在上海举办金融量化策略回测Workshop,汇聚多位行业专家,围绕量化投资的最佳实践、数据隐私安全、量化策略回测方案等议题进行深入探讨。活动特别设计了动手实践环节,帮助参会者亲身体验阿里云产品功能,涵盖EHPC量化回测和Argo Workflows量化回测两大主题,旨在提升量化投研效率与安全性。
云上金融量化策略回测方案与最佳实践
|
4天前
|
人工智能 自然语言处理 前端开发
从0开始打造一款APP:前端+搭建本机服务,定制暖冬卫衣先到先得
通义灵码携手科技博主@玺哥超carry 打造全网第一个完整的、面向普通人的自然语言编程教程。完全使用 AI,再配合简单易懂的方法,只要你会打字,就能真正做出一个完整的应用。
4994 18
|
15天前
|
人工智能 自动驾驶 大数据
预告 | 阿里云邀您参加2024中国生成式AI大会上海站,马上报名
大会以“智能跃进 创造无限”为主题,设置主会场峰会、分会场研讨会及展览区,聚焦大模型、AI Infra等热点议题。阿里云智算集群产品解决方案负责人丛培岩将出席并发表《高性能智算集群设计思考与实践》主题演讲。观众报名现已开放。
|
8天前
|
自然语言处理 数据可视化 API
Qwen系列模型+GraphRAG/LightRAG/Kotaemon从0开始构建中医方剂大模型知识图谱问答
本文详细记录了作者在短时间内尝试构建中医药知识图谱的过程,涵盖了GraphRAG、LightRAG和Kotaemon三种图RAG架构的对比与应用。通过实际操作,作者不仅展示了如何利用这些工具构建知识图谱,还指出了每种工具的优势和局限性。尽管初步构建的知识图谱在数据处理、实体识别和关系抽取等方面存在不足,但为后续的优化和改进提供了宝贵的经验和方向。此外,文章强调了知识图谱构建不仅仅是技术问题,还需要深入整合领域知识和满足用户需求,体现了跨学科合作的重要性。
|
3天前
|
人工智能 容器
三句话开发一个刮刮乐小游戏!暖ta一整个冬天!
本文介绍了如何利用千问开发一款情侣刮刮乐小游戏,通过三步简单指令实现从单个功能到整体框架,再到多端优化的过程,旨在为生活增添乐趣,促进情感交流。在线体验地址已提供,鼓励读者动手尝试,探索编程与AI结合的无限可能。
|
1月前
|
存储 人工智能 弹性计算
阿里云弹性计算_加速计算专场精华概览 | 2024云栖大会回顾
2024年9月19-21日,2024云栖大会在杭州云栖小镇举行,阿里云智能集团资深技术专家、异构计算产品技术负责人王超等多位产品、技术专家,共同带来了题为《AI Infra的前沿技术与应用实践》的专场session。本次专场重点介绍了阿里云AI Infra 产品架构与技术能力,及用户如何使用阿里云灵骏产品进行AI大模型开发、训练和应用。围绕当下大模型训练和推理的技术难点,专家们分享了如何在阿里云上实现稳定、高效、经济的大模型训练,并通过多个客户案例展示了云上大模型训练的显著优势。
|
8天前
|
Cloud Native Apache 流计算
PPT合集|Flink Forward Asia 2024 上海站
Apache Flink 年度技术盛会聚焦“回顾过去,展望未来”,涵盖流式湖仓、流批一体、Data+AI 等八大核心议题,近百家厂商参与,深入探讨前沿技术发展。小松鼠为大家整理了 FFA 2024 演讲 PPT ,可在线阅读和下载。
3406 10
PPT合集|Flink Forward Asia 2024 上海站
|
21天前
|
人工智能 自然语言处理 前端开发
100个降噪蓝牙耳机免费领,用通义灵码从 0 开始打造一个完整APP
打开手机,录制下你完成的代码效果,发布到你的社交媒体,前 100 个@玺哥超Carry、@通义灵码的粉丝,可以免费获得一个降噪蓝牙耳机。
5922 16
|
3天前
|
消息中间件 人工智能 运维
12月更文特别场——寻找用云高手,分享云&AI实践
我们寻找你,用云高手,欢迎分享你的真知灼见!
448 36
|
2天前
|
云安全 人工智能 安全