Android APT开发教程 六 使用注解替代setOnClickListener还有注释给String赋值
2018-01-24 16:22
711 查看
github项目代码地址
https://github.com/979451341/TestAPT
如下图
因为之前做了注解代替int赋值和findViewById,所以我们只用在原来的代码改动就好了
元注解
@TestString("aaaa")
String data;
注解处理器代码生成
bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = \"%s\"",item.getSimpleName(),testString.value()));
说了就是在“”里面再用“就必须要加个\,否则系统判错,这个注意一下就好,像其他的基础类型用注解赋值都是一个样,换个元注解就好了
以下是注解处理器完整代码:
https://github.com/979451341/TestAPT
1.注释代替setOnClickListener
这个注解能够通过绑定控件id和函数,使点击这个控件的时候触发这个函数如下图
@OnClick(R.id.tv1) public void click(){ c++; tv1.setText(c+""); }首先是元注解,ElementType指定为函数,并设置一个int类型的变量用来存储id
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OnClick { int value() default 0; }然后我们想一下生成什么代码,既然是要用注解代替setOnClick,那我们就生成setOnClick代码
因为之前做了注解代替int赋值和findViewById,所以我们只用在原来的代码改动就好了
for (Element item : members) { TestInt diView = item.getAnnotation(TestInt.class); OnClick onClick = item.getAnnotation(OnClick.class); if (diView == null && onClick == null){ continue; } if(diView != null){ if(item.asType().getKind() == INT) bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = %s",item.getSimpleName(),diView.value())); if(item.asType().getKind() == DECLARED) bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = (%s)activity.findViewById(%s)",item.getSimpleName(),item.asType().toString(),diView.value())); } if(onClick != null){ String name = item.getSimpleName().toString(); bindViewMethodSpecBuilder.addStatement(String.format("activity.findViewById(%s).setOnClickListener(new android.view.View.OnClickListener() {\n" + " @Override\n" + " public void onClick(android.view.View v) {\n" +"activity.%s();"+ " \n" + " }\n" + " });",onClick.value(),name)); } }
2.用注解给String赋值
这个应该不写的,因为觉得很low,但是我搞了半天才知道咋弄,不说了直接上关键代码元注解
@Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface TestString { String value() default ""; }使用
@TestString("aaaa")
String data;
注解处理器代码生成
bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = \"%s\"",item.getSimpleName(),testString.value()));
说了就是在“”里面再用“就必须要加个\,否则系统判错,这个注意一下就好,像其他的基础类型用注解赋值都是一个样,换个元注解就好了
以下是注解处理器完整代码:
@AutoService(Processor.class) public class TestProcessor extends AbstractProcessor { private Elements elementUtils; @Override public Set<String> getSupportedAnnotationTypes() { // 规定需要处理的注解 return Collections.singleton(TestActivity.class.getCanonicalName()); } @Override public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(TestActivity.class); for (Element element : elements) { // 判断是否Class TypeElement typeElement = (TypeElement) element; List<? extends Element> members = elementUtils.getAllMembers(typeElement); TestActivity activity = typeElement.getAnnotation(TestActivity.class); MethodSpec.Builder bindViewMethodSpecBuilder = MethodSpec.methodBuilder("setDefualt") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(TypeName.VOID) .addParameter(ClassName.get(typeElement.asType()), "activity",Modifier.FINAL); if(activity == null){ continue; } bindViewMethodSpecBuilder.addStatement(String.format("activity.setContentView(%s)",activity.value())); for (Element item : members) { TestInt diView = item.getAnnotation(TestInt.class); OnClick onClick = item.getAnnotation(OnClick.class); TestString testString = item.getAnnotation(TestString.class); if (diView == null && onClick == null && testString == null){ continue; } if(diView != null){ if(item.asType().getKind() == INT) bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = %s",item.getSimpleName(),diView.value())); if(item.asType().getKind() == DECLARED) bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = (%s)activity.findViewById(%s)",item.getSimpleName(),item.asType().toString(),diView.value())); } if(onClick != null){ String name = item.getSimpleName().toString(); bindViewMethodSpecBuilder.addStatement(String.format("activity.findViewById(%s).setOnClickListener(new android.view.View.OnClickListener() {\n" + " @Override\n" + " public void onClick(android.view.View v) {\n" +"activity.%s();"+ " \n" + " }\n" + " });",onClick.value(),name)); } if(testString != null){ bindViewMethodSpecBuilder.addStatement(String.format("activity.%s = \"%s\"",item.getSimpleName(),testString.value())); } } TypeSpec typeSpec = TypeSpec.classBuilder("Test" + element.getSimpleName()) .superclass(TypeName.get(typeElement.asType())) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addMethod(bindViewMethodSpecBuilder.build()) .build(); JavaFile javaFile = JavaFile.builder(getPackageName(typeElement), typeSpec).build(); try { javaFile.writeTo(processingEnv.getFiler()); } catch (IOException e) { e.printStackTrace(); } } return true; } private String getPackageName(TypeElement type) { return elementUtils.getPackageOf(type).getQualifiedName().toString(); } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); elementUtils = processingEnv.getElementUtils(); } @Override public SourceVersion getSupportedSourceVersion() { return SourceVersion.RELEASE_7; } }这样就好了,大部分关于Butterknife的常用注解,我们都实现了,这个系列还会写下去,应该继续模仿一些很有名的框架使用的注解做模仿。
相关文章推荐
- Android APT开发教程 六 使用注解替代setOnClickListener还有注释
- Android APT开发教程 五 使用注释完成findViewById和setContentView
- Android APT开发教程 五 使用注释完成findViewById和setConten
- 使用编译时注解annotationProcessor(取代android-apt)开发组件化路由框架
- Android中使用AlertDialog,使用函数setButton()出现的关于“new OnClickListener"错误
- Android APT开发教程 四 apt生成代码与所注释元素之间的交互
- Android开发中CheckBox的setOnClickListener和setOnCheckedChangeListener的不同之处在哪?
- Android开发最强模拟器Genymotion的安装及使用教程。附注释图详解
- 从零开始学android开发-View的setOnClickListener的添加方法
- Android APT开发教程 一 Annotation注解
- Android setOnClickListener使用方法
- Android开发中CheckBox、setOnClickListener和setOnCheckedChangeListener的不同之处在哪
- Android 注解开发 ButterKnife使用详解及教程
- Android快速开发工具ButterKnife Zelezny注解框架使用教程
- Android APT开发教程 四 apt生成代码与所注释元素之间的交互
- android开发Enum (枚举)的更轻量级的替代方案 —— @IntDef的使用 原创 2017年11月28日 09:17:58 77 最近在翻看Android源码的时候,无意中看到这么一个注解,
- android通过注解实现findViewById 和 setOnClickListener
- 关于android Activity中注解的使用,省去无用的findviewbyid....setonclick.....
- <Android>setOnClickListener使用无效,报错null pointer
- Android APT开发教程 一 Annotation注解