1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
//例如 @BindColor(android.R.color.black) @ColorInt int blackColor;
//将会生成代码 target.blackColor = ContextCompat.getColor(context, android.R.color.black);
//ResourceMethod方法指的是生成代码的对象
final class FieldResourceBinding implements ResourceBinding {
enum Type {
BITMAP(new ResourceMethod(BindingSet.BITMAP_FACTORY, "decodeResource", true, 1)),
BOOL("getBoolean"),
COLOR(new ResourceMethod(BindingSet.CONTEXT_COMPAT, "getColor", false, 1),
new ResourceMethod(null, "getColor", false, 23)),
COLOR_STATE_LIST(new ResourceMethod(BindingSet.CONTEXT_COMPAT, "getColorStateList", false, 1),
new ResourceMethod(null, "getColorStateList", false, 23)),
DIMEN_AS_INT("getDimensionPixelSize"),
DIMEN_AS_FLOAT("getDimension"),
FLOAT(new ResourceMethod(BindingSet.UTILS, "getFloat", false, 1)),
INT("getInteger"),
INT_ARRAY("getIntArray"),
STRING("getString"),
STRING_ARRAY("getStringArray"),
TEXT_ARRAY("getTextArray"),
TYPED_ARRAY("obtainTypedArray");
private final List<ResourceMethod> methods;
Type(ResourceMethod... methods) {
List<ResourceMethod> methodList = new ArrayList<>(methods.length);
Collections.addAll(methodList, methods);
Collections.sort(methodList);
Collections.reverse(methodList);
this.methods = unmodifiableList(methodList);
}
Type(String methodName) {
methods = singletonList(new ResourceMethod(null, methodName, true, 1));
}
ResourceMethod methodForSdk(int sdk) {
for (ResourceMethod method : methods) {
if (method.sdk <= sdk) {
return method;
}
}
throw new AssertionError();
}
}
//资源方法
static final class ResourceMethod implements Comparable<ResourceMethod> {
final ClassName typeName;//类名
final String name;//方法名
final boolean requiresResources;
final int sdk;//sdk版本号 因为sdk版本号不一样,调用的方法可能不一样。
ResourceMethod(ClassName typeName, String name, boolean requiresResources, int sdk) {
this.typeName = typeName;
this.name = name;
this.requiresResources = requiresResources;
this.sdk = sdk;
}
@Override
public int compareTo(ResourceMethod other) {
return Integer.compare(sdk, other.sdk);//按照sdk排序
}
}
//构造函数
private final Id id;
private final String name;
private final Type type;
FieldResourceBinding(Id id, String name, Type type) {
this.id = id;
this.name = name;
this.type = type;
}
@Override
public Id id() {
return id;
}
@Override
public boolean requiresResources(int sdk) {
return type.methodForSdk(sdk).requiresResources;
}
@Override
public CodeBlock render(int sdk) {
ResourceMethod method = type.methodForSdk(sdk);
if (method.typeName == null) {
if (method.requiresResources) {
return CodeBlock.of("target.$L = res.$L($L)", name, method.name, id.code);
}
return CodeBlock.of("target.$L = context.$L($L)", name, method.name, id.code);
}
if (method.requiresResources) {
return CodeBlock.of("target.$L = $T.$L(res, $L)", name, method.typeName, method.name,
id.code);
}
return CodeBlock.of("target.$L = $T.$L(context, $L)", name, method.typeName, method.name,
id.code);
}
}
|