-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathVectorHelper
More file actions
140 lines (125 loc) · 6.18 KB
/
VectorHelper
File metadata and controls
140 lines (125 loc) · 6.18 KB
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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.aesean.utils;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.text.TextUtils;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* VectorHelper
*
* @author xl
* @version V1.0
* @since 16/7/8
*/
public class VectorHelper {
private static final String TAG = "VectorHelper";
private static final List<String> NEED_CAST_TO_INT = new ArrayList<>();
static {
NEED_CAST_TO_INT.add("mStrokeColor");
NEED_CAST_TO_INT.add("mFillColor");
NEED_CAST_TO_INT.add("mFillRule");
}
public static final String PROPERTY_NAME_STROKE_COLOR_INT = "mStrokeColor";
public static final String PROPERTY_NAME_STROKE_WIDTH_FLOAT = "mStrokeWidth";
public static final String PROPERTY_NAME_FILL_COLOR_INT = "mFillColor";
public static final String PROPERTY_NAME_STROKE_ALPHA_FLOAT = "mStrokeAlpha";
public static final String PROPERTY_NAME_FILL_RULE_INT = "mFillRule";
public static final String PROPERTY_NAME_FILL_ALPHA_FLOAT = "mFillAlpha";
public static final String PROPERTY_NAME_TRIM_PATH_START_FLOAT = "mTrimPathStart";
public static final String PROPERTY_NAME_TRIM_PATH_END_FLOAT = "mTrimPathEnd";
public static final String PROPERTY_NAME_TRIM_PATH_OFFSET_FLOAT = "mTrimPathOffset";
public static final String PROPERTY_NAME_STROKE_MITER_LIMIT_FLOAT = "mStrokeMiterlimit";
private static boolean isAvailablePropertyName(String propertyName) {
return !TextUtils.isEmpty(propertyName)
&& (propertyName.equals(PROPERTY_NAME_STROKE_COLOR_INT)
|| propertyName.equals(PROPERTY_NAME_STROKE_WIDTH_FLOAT)
|| propertyName.equals(PROPERTY_NAME_FILL_COLOR_INT)
|| propertyName.equals(PROPERTY_NAME_STROKE_ALPHA_FLOAT)
|| propertyName.equals(PROPERTY_NAME_FILL_RULE_INT)
|| propertyName.equals(PROPERTY_NAME_FILL_ALPHA_FLOAT)
|| propertyName.equals(PROPERTY_NAME_TRIM_PATH_START_FLOAT)
|| propertyName.equals(PROPERTY_NAME_TRIM_PATH_END_FLOAT)
|| propertyName.equals(PROPERTY_NAME_TRIM_PATH_OFFSET_FLOAT)
|| propertyName.equals(PROPERTY_NAME_STROKE_MITER_LIMIT_FLOAT));
}
/**
* 通过反射设置AnimatedVectorDrawable的各个属性
*
* @param animatedVectorDrawable AnimatedVectorDrawable对象
* @param groupName 要设置的组名称
* @param propertyName 需要设置的属性名称,属性名称参考当前类PROPERTY_NAME开头的静态String
* @param value 需要设置的数值
* @return true设置成功, false设置失败
*/
public static boolean reflect(AnimatedVectorDrawable animatedVectorDrawable, String groupName, String propertyName, float value) {
if (!isAvailablePropertyName(propertyName)) {
throw new RuntimeException("不支持的属性名:" + propertyName);
}
try {
Class<? extends AnimatedVectorDrawable> animatedVectorDrawableClass = animatedVectorDrawable.getClass();
Field mAnimatedVectorStateField = animatedVectorDrawableClass.getDeclaredField("mAnimatedVectorState");
mAnimatedVectorStateField.setAccessible(true);
Object mAnimatedVectorState = mAnimatedVectorStateField.get(animatedVectorDrawable);
if (mAnimatedVectorState == null) {
return false;
}
Class<?> mAnimatedVectorStateClass = mAnimatedVectorState.getClass();
Field mVectorDrawableField = mAnimatedVectorStateClass.getDeclaredField("mVectorDrawable");
mVectorDrawableField.setAccessible(true);
Object mVectorDrawable = mVectorDrawableField.get(mAnimatedVectorState);
if (mVectorDrawable == null) {
return false;
}
Class<?> mVectorDrawableClass = mVectorDrawable.getClass();
Method getTargetByNameMethod = mVectorDrawableClass.getDeclaredMethod("getTargetByName", String.class);
getTargetByNameMethod.setAccessible(true);
Object propertyTarget = getTargetByNameMethod.invoke(mVectorDrawable, groupName);
if (propertyTarget == null) {
return false;
}
Class<?> propertyTargetClass = propertyTarget.getClass();
Field mChildrenField = propertyTargetClass.getDeclaredField("mChildren");
mChildrenField.setAccessible(true);
Object mChildren = mChildrenField.get(propertyTarget);
if (mChildren == null) {
return false;
}
// 这里从源码可以查到就是List,这里也可以直接强转为List
if (mChildren instanceof List) {
List list = (List) mChildren;
boolean needCastToInt = needCastToInt(propertyName);
for (Object child : list) {
Class<?> childClass = child.getClass();
Field mFillColorField = childClass.getDeclaredField(propertyName);
mFillColorField.setAccessible(true);
if (needCastToInt) {
mFillColorField.set(child, (int) value);
} else {
mFillColorField.set(child, value);
}
}
animatedVectorDrawable.invalidateSelf();
return true;
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
Log.e(TAG, "NoSuchFieldException: ", e);
} catch (IllegalAccessException e) {
e.printStackTrace();
Log.e(TAG, "IllegalAccessException: ", e);
} catch (NoSuchMethodException e) {
e.printStackTrace();
Log.e(TAG, "NoSuchMethodException: ", e);
} catch (InvocationTargetException e) {
e.printStackTrace();
Log.e(TAG, "InvocationTargetException: ", e);
}
return false;
}
private static boolean needCastToInt(String propertyName) {
return NEED_CAST_TO_INT.contains(propertyName);
}
}