CustomSupport.java
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.constraintlayout.motion.utils;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.View;
import androidx.constraintlayout.motion.widget.Debug;
import androidx.constraintlayout.widget.ConstraintAttribute;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class CustomSupport {
private static final String TAG = "CustomSupport";
/**
* sets the interpolated value
* @param att
* @param view
* @param value
*/
public static void setInterpolatedValue(ConstraintAttribute att, View view, float[] value) {
Class<? extends View> viewClass = view.getClass();
String methodName = "set" + att.getName();
try {
Method method;
switch (att.getType()) {
case INT_TYPE:
method = viewClass.getMethod(methodName, Integer.TYPE);
method.invoke(view, (int) value[0]);
break;
case FLOAT_TYPE:
method = viewClass.getMethod(methodName, Float.TYPE);
method.invoke(view, value[0]);
break;
case COLOR_DRAWABLE_TYPE: {
method = viewClass.getMethod(methodName, Drawable.class);
int r = clamp((int) ((float) Math.pow(value[0], 1.0 / 2.2) * 255.0f));
int g = clamp((int) ((float) Math.pow(value[1], 1.0 / 2.2) * 255.0f));
int b = clamp((int) ((float) Math.pow(value[2], 1.0 / 2.2) * 255.0f));
int a = clamp((int) (value[3] * 255.0f));
int color = a << 24 | (r << 16) | (g << 8) | b;
ColorDrawable drawable = new ColorDrawable(); // TODO cache
drawable.setColor(color);
method.invoke(view, drawable);
}
break;
case COLOR_TYPE:
method = viewClass.getMethod(methodName, Integer.TYPE);
int r = clamp((int) ((float) Math.pow(value[0], 1.0 / 2.2) * 255.0f));
int g = clamp((int) ((float) Math.pow(value[1], 1.0 / 2.2) * 255.0f));
int b = clamp((int) ((float) Math.pow(value[2], 1.0 / 2.2) * 255.0f));
int a = clamp((int) (value[3] * 255.0f));
int color = a << 24 | (r << 16) | (g << 8) | b;
method.invoke(view, color);
break;
case STRING_TYPE:
throw new RuntimeException("unable to interpolate strings " + att.getName());
case BOOLEAN_TYPE:
method = viewClass.getMethod(methodName, Boolean.TYPE);
method.invoke(view, value[0] > 0.5f);
break;
case DIMENSION_TYPE:
method = viewClass.getMethod(methodName, Float.TYPE);
method.invoke(view, value[0]);
break;
}
} catch (NoSuchMethodException e) {
Log.e(TAG, "no method " + methodName + " on View \"" + Debug.getName(view) + "\"");
e.printStackTrace();
} catch (IllegalAccessException e) {
Log.e(TAG, "cannot access method " + methodName + " on View \""
+ Debug.getName(view) + "\"");
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
private static int clamp(int c) {
int n = 255;
c &= ~(c >> 31);
c -= n;
c &= (c >> 31);
c += n;
return c;
}
}