我们设置了 colorFilter
属性,作用相当于 tint
,重新运行后,可以看到如下效果:
需要我们注意的是,这里的自定义属性的 attributeName
对应的值并不一定是在 xml 布局文件中控件对应的属性名称,而是在对应控件中拥有 setter 设置的属性名称。怎么理解呢?其实归根结底 CustomAttribute 内部还是利用的反射,从下面的部分源码中就能够察觉到:
public void applyCustomAttributes(ConstraintLayout constraintLayout) {
int count = constraintLayout.getChildCount();
for(int i = 0; i < count; ++i) {
View view = constraintLayout.getChildAt(i);
int id = view.getId();
if (!this.mConstraints.containsKey(id)) {
Log.v(“ConstraintSet”, "id unknown " + Debug.getName(view));
} else {
if (this.mForceId && id == -1) {
throw new RuntimeException(“All children of ConstraintLayout must have ids to use ConstraintSet”);
}
if (this.mConstraints.containsKey(id)) {
ConstraintSet.Constraint constraint = (ConstraintSet.Constraint)this.mConstraints.get(id);
ConstraintAttribute.setAttributes(view, constraint.mCustomConstraints);
}
}
}
}
…
public static void setAttributes(View view, HashMap<String, ConstraintAttribute> map) {
Class<? extends View> viewClass = view.getClass();
Iterator var3 = map.keySet().iterator();
while(var3.hasNext()) {
String name = (String)var3.next();
ConstraintAttribute constraintAttribute = (ConstraintAttribute)map.get(name);
String methodName = “set” + name;
try {
Method method;
switch(constraintAttribute.mType) {
case COLOR_TYPE:
method = viewClass.getMethod(methodName, Integer.TYPE);
method.invoke(view, constraintAttribute.mColorValue);
break;
case COLOR_DRAWABLE_TYPE:
method = viewClass.getMethod(methodName, Drawable.class);
ColorDrawable drawable = new ColorDrawable();
drawable.setColor(constraintAttribute.mColorValue);
method.invoke(view, drawable);
break;
case INT_TYPE:
method = viewClass