1001 lines
39 KiB
Java
1001 lines
39 KiB
Java
package com.gh.common.databind;
|
||
|
||
import android.content.res.Resources;
|
||
import android.graphics.drawable.Drawable;
|
||
import android.graphics.drawable.GradientDrawable;
|
||
import android.graphics.drawable.InsetDrawable;
|
||
import android.graphics.drawable.StateListDrawable;
|
||
import android.view.View;
|
||
|
||
import java.lang.annotation.Retention;
|
||
import java.lang.annotation.RetentionPolicy;
|
||
import java.lang.annotation.Target;
|
||
import java.lang.reflect.Field;
|
||
|
||
import androidx.annotation.ColorInt;
|
||
import androidx.annotation.IntDef;
|
||
import androidx.databinding.BindingAdapter;
|
||
|
||
import static java.lang.annotation.ElementType.FIELD;
|
||
import static java.lang.annotation.ElementType.PARAMETER;
|
||
|
||
public class DrawablesBindingAdapter {
|
||
private static final String TAG = "Drawables";
|
||
|
||
private static final int INVALID = 0;
|
||
private static final int[] TMP_PADDING = new int[4];
|
||
|
||
|
||
// normal, checked, checkable, enabled, focused, pressed, selected
|
||
@BindingAdapter(value = {
|
||
"drawable_shapeMode",
|
||
"drawable_solidColor",
|
||
"drawable_strokeColor",
|
||
"drawable_strokeWidth",
|
||
"drawable_strokeDash",
|
||
"drawable_strokeDashGap",
|
||
"drawable_radius",
|
||
"drawable_radiusLT",
|
||
"drawable_radiusLB",
|
||
"drawable_radiusRT",
|
||
"drawable_radiusRB",
|
||
"drawable_startColor",
|
||
"drawable_centerColor",
|
||
"drawable_endColor",
|
||
"drawable_orientation",
|
||
"drawable_gradientType",
|
||
"drawable_radialCenterX",
|
||
"drawable_radialCenterY",
|
||
"drawable_radialRadius",
|
||
"drawable_width",
|
||
"drawable_height",
|
||
"drawable_marginLeft",
|
||
"drawable_marginTop",
|
||
"drawable_marginRight",
|
||
"drawable_marginBottom",
|
||
"drawable_ringThickness",
|
||
"drawable_ringThicknessRatio",
|
||
"drawable_ringInnerRadius",
|
||
"drawable_ringInnerRadiusRatio",
|
||
|
||
"drawable_checked_shapeMode",
|
||
"drawable_checked_solidColor",
|
||
"drawable_checked_strokeColor",
|
||
"drawable_checked_strokeWidth",
|
||
"drawable_checked_strokeDash",
|
||
"drawable_checked_strokeDashGap",
|
||
"drawable_checked_radius",
|
||
"drawable_checked_radiusLT",
|
||
"drawable_checked_radiusLB",
|
||
"drawable_checked_radiusRT",
|
||
"drawable_checked_radiusRB",
|
||
"drawable_checked_startColor",
|
||
"drawable_checked_centerColor",
|
||
"drawable_checked_endColor",
|
||
"drawable_checked_orientation",
|
||
"drawable_checked_gradientType",
|
||
"drawable_checked_radialCenterX",
|
||
"drawable_checked_radialCenterY",
|
||
"drawable_checked_radialRadius",
|
||
"drawable_checked_width",
|
||
"drawable_checked_height",
|
||
"drawable_checked_marginLeft",
|
||
"drawable_checked_marginTop",
|
||
"drawable_checked_marginRight",
|
||
"drawable_checked_marginBottom",
|
||
"drawable_checked_ringThickness",
|
||
"drawable_checked_ringThicknessRatio",
|
||
"drawable_checked_ringInnerRadius",
|
||
"drawable_checked_ringInnerRadiusRatio",
|
||
|
||
"drawable_checkable_shapeMode",
|
||
"drawable_checkable_solidColor",
|
||
"drawable_checkable_strokeColor",
|
||
"drawable_checkable_strokeWidth",
|
||
"drawable_checkable_strokeDash",
|
||
"drawable_checkable_strokeDashGap",
|
||
"drawable_checkable_radius",
|
||
"drawable_checkable_radiusLT",
|
||
"drawable_checkable_radiusLB",
|
||
"drawable_checkable_radiusRT",
|
||
"drawable_checkable_radiusRB",
|
||
"drawable_checkable_startColor",
|
||
"drawable_checkable_centerColor",
|
||
"drawable_checkable_endColor",
|
||
"drawable_checkable_orientation",
|
||
"drawable_checkable_gradientType",
|
||
"drawable_checkable_radialCenterX",
|
||
"drawable_checkable_radialCenterY",
|
||
"drawable_checkable_radialRadius",
|
||
"drawable_checkable_width",
|
||
"drawable_checkable_height",
|
||
"drawable_checkable_marginLeft",
|
||
"drawable_checkable_marginTop",
|
||
"drawable_checkable_marginRight",
|
||
"drawable_checkable_marginBottom",
|
||
"drawable_checkable_ringThickness",
|
||
"drawable_checkable_ringThicknessRatio",
|
||
"drawable_checkable_ringInnerRadius",
|
||
"drawable_checkable_ringInnerRadiusRatio",
|
||
|
||
"drawable_enabled_shapeMode",
|
||
"drawable_enabled_solidColor",
|
||
"drawable_enabled_strokeColor",
|
||
"drawable_enabled_strokeWidth",
|
||
"drawable_enabled_strokeDash",
|
||
"drawable_enabled_strokeDashGap",
|
||
"drawable_enabled_radius",
|
||
"drawable_enabled_radiusLT",
|
||
"drawable_enabled_radiusLB",
|
||
"drawable_enabled_radiusRT",
|
||
"drawable_enabled_radiusRB",
|
||
"drawable_enabled_startColor",
|
||
"drawable_enabled_centerColor",
|
||
"drawable_enabled_endColor",
|
||
"drawable_enabled_orientation",
|
||
"drawable_enabled_gradientType",
|
||
"drawable_enabled_radialCenterX",
|
||
"drawable_enabled_radialCenterY",
|
||
"drawable_enabled_radialRadius",
|
||
"drawable_enabled_width",
|
||
"drawable_enabled_height",
|
||
"drawable_enabled_marginLeft",
|
||
"drawable_enabled_marginTop",
|
||
"drawable_enabled_marginRight",
|
||
"drawable_enabled_marginBottom",
|
||
"drawable_enabled_ringThickness",
|
||
"drawable_enabled_ringThicknessRatio",
|
||
"drawable_enabled_ringInnerRadius",
|
||
"drawable_enabled_ringInnerRadiusRatio",
|
||
|
||
"drawable_focused_shapeMode",
|
||
"drawable_focused_solidColor",
|
||
"drawable_focused_strokeColor",
|
||
"drawable_focused_strokeWidth",
|
||
"drawable_focused_strokeDash",
|
||
"drawable_focused_strokeDashGap",
|
||
"drawable_focused_radius",
|
||
"drawable_focused_radiusLT",
|
||
"drawable_focused_radiusLB",
|
||
"drawable_focused_radiusRT",
|
||
"drawable_focused_radiusRB",
|
||
"drawable_focused_startColor",
|
||
"drawable_focused_centerColor",
|
||
"drawable_focused_endColor",
|
||
"drawable_focused_orientation",
|
||
"drawable_focused_gradientType",
|
||
"drawable_focused_radialCenterX",
|
||
"drawable_focused_radialCenterY",
|
||
"drawable_focused_radialRadius",
|
||
"drawable_focused_width",
|
||
"drawable_focused_height",
|
||
"drawable_focused_marginLeft",
|
||
"drawable_focused_marginTop",
|
||
"drawable_focused_marginRight",
|
||
"drawable_focused_marginBottom",
|
||
"drawable_focused_ringThickness",
|
||
"drawable_focused_ringThicknessRatio",
|
||
"drawable_focused_ringInnerRadius",
|
||
"drawable_focused_ringInnerRadiusRatio",
|
||
|
||
"drawable_pressed_shapeMode",
|
||
"drawable_pressed_solidColor",
|
||
"drawable_pressed_strokeColor",
|
||
"drawable_pressed_strokeWidth",
|
||
"drawable_pressed_strokeDash",
|
||
"drawable_pressed_strokeDashGap",
|
||
"drawable_pressed_radius",
|
||
"drawable_pressed_radiusLT",
|
||
"drawable_pressed_radiusLB",
|
||
"drawable_pressed_radiusRT",
|
||
"drawable_pressed_radiusRB",
|
||
"drawable_pressed_startColor",
|
||
"drawable_pressed_centerColor",
|
||
"drawable_pressed_endColor",
|
||
"drawable_pressed_orientation",
|
||
"drawable_pressed_gradientType",
|
||
"drawable_pressed_radialCenterX",
|
||
"drawable_pressed_radialCenterY",
|
||
"drawable_pressed_radialRadius",
|
||
"drawable_pressed_width",
|
||
"drawable_pressed_height",
|
||
"drawable_pressed_marginLeft",
|
||
"drawable_pressed_marginTop",
|
||
"drawable_pressed_marginRight",
|
||
"drawable_pressed_marginBottom",
|
||
"drawable_pressed_ringThickness",
|
||
"drawable_pressed_ringThicknessRatio",
|
||
"drawable_pressed_ringInnerRadius",
|
||
"drawable_pressed_ringInnerRadiusRatio",
|
||
|
||
"drawable_selected_shapeMode",
|
||
"drawable_selected_solidColor",
|
||
"drawable_selected_strokeColor",
|
||
"drawable_selected_strokeWidth",
|
||
"drawable_selected_strokeDash",
|
||
"drawable_selected_strokeDashGap",
|
||
"drawable_selected_radius",
|
||
"drawable_selected_radiusLT",
|
||
"drawable_selected_radiusLB",
|
||
"drawable_selected_radiusRT",
|
||
"drawable_selected_radiusRB",
|
||
"drawable_selected_startColor",
|
||
"drawable_selected_centerColor",
|
||
"drawable_selected_endColor",
|
||
"drawable_selected_orientation",
|
||
"drawable_selected_gradientType",
|
||
"drawable_selected_radialCenterX",
|
||
"drawable_selected_radialCenterY",
|
||
"drawable_selected_radialRadius",
|
||
"drawable_selected_width",
|
||
"drawable_selected_height",
|
||
"drawable_selected_marginLeft",
|
||
"drawable_selected_marginTop",
|
||
"drawable_selected_marginRight",
|
||
"drawable_selected_marginBottom",
|
||
"drawable_selected_ringThickness",
|
||
"drawable_selected_ringThicknessRatio",
|
||
"drawable_selected_ringInnerRadius",
|
||
"drawable_selected_ringInnerRadiusRatio",
|
||
|
||
// normal, checked, checkable, enabled, focused, pressed, selected
|
||
|
||
"drawable",
|
||
"drawable_checked",
|
||
"drawable_checkable",
|
||
"drawable_enabled",
|
||
"drawable_focused",
|
||
"drawable_pressed",
|
||
"drawable_selected",
|
||
|
||
}, requireAll = false)
|
||
public static void setViewBackground(
|
||
View view,
|
||
|
||
@ShapeMode int shapeMode,
|
||
@ColorInt Integer solidColor,
|
||
@ColorInt int strokeColor,
|
||
float strokeWidth,
|
||
float strokeDash,
|
||
float strokeDashGap,
|
||
float radius,
|
||
float radiusLT,
|
||
float radiusLB,
|
||
float radiusRT,
|
||
float radiusRB,
|
||
@ColorInt Integer startColor,
|
||
@ColorInt Integer centerColor,
|
||
@ColorInt Integer endColor,
|
||
@Orientation int orientation,
|
||
@GradientType int gradientType,
|
||
Float radialCenterX,
|
||
Float radialCenterY,
|
||
float radialRadius,
|
||
float width,
|
||
float height,
|
||
float marginLeft,
|
||
float marginTop,
|
||
float marginRight,
|
||
float marginBottom,
|
||
float ringThickness,
|
||
float ringThicknessRatio,
|
||
float ringInnerRadius,
|
||
float ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int checked_shapeMode,
|
||
@ColorInt Integer checked_solidColor,
|
||
@ColorInt int checked_strokeColor,
|
||
float checked_strokeWidth,
|
||
float checked_strokeDash,
|
||
float checked_strokeDashGap,
|
||
float checked_radius,
|
||
float checked_radiusLT,
|
||
float checked_radiusLB,
|
||
float checked_radiusRT,
|
||
float checked_radiusRB,
|
||
@ColorInt Integer checked_startColor,
|
||
@ColorInt Integer checked_centerColor,
|
||
@ColorInt Integer checked_endColor,
|
||
@Orientation int checked_orientation,
|
||
@GradientType int checked_gradientType,
|
||
Float checked_radialCenterX,
|
||
Float checked_radialCenterY,
|
||
float checked_radialRadius,
|
||
float checked_width,
|
||
float checked_height,
|
||
float checked_marginLeft,
|
||
float checked_marginTop,
|
||
float checked_marginRight,
|
||
float checked_marginBottom,
|
||
float checked_ringThickness,
|
||
float checked_ringThicknessRatio,
|
||
float checked_ringInnerRadius,
|
||
float checked_ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int checkable_shapeMode,
|
||
@ColorInt Integer checkable_solidColor,
|
||
@ColorInt int checkable_strokeColor,
|
||
float checkable_strokeWidth,
|
||
float checkable_strokeDash,
|
||
float checkable_strokeDashGap,
|
||
float checkable_radius,
|
||
float checkable_radiusLT,
|
||
float checkable_radiusLB,
|
||
float checkable_radiusRT,
|
||
float checkable_radiusRB,
|
||
@ColorInt Integer checkable_startColor,
|
||
@ColorInt Integer checkable_centerColor,
|
||
@ColorInt Integer checkable_endColor,
|
||
@Orientation int checkable_orientation,
|
||
@GradientType int checkable_gradientType,
|
||
Float checkable_radialCenterX,
|
||
Float checkable_radialCenterY,
|
||
float checkable_radialRadius,
|
||
float checkable_width,
|
||
float checkable_height,
|
||
float checkable_marginLeft,
|
||
float checkable_marginTop,
|
||
float checkable_marginRight,
|
||
float checkable_marginBottom,
|
||
float checkable_ringThickness,
|
||
float checkable_ringThicknessRatio,
|
||
float checkable_ringInnerRadius,
|
||
float checkable_ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int enabled_shapeMode,
|
||
@ColorInt Integer enabled_solidColor,
|
||
@ColorInt int enabled_strokeColor,
|
||
float enabled_strokeWidth,
|
||
float enabled_strokeDash,
|
||
float enabled_strokeDashGap,
|
||
float enabled_radius,
|
||
float enabled_radiusLT,
|
||
float enabled_radiusLB,
|
||
float enabled_radiusRT,
|
||
float enabled_radiusRB,
|
||
@ColorInt Integer enabled_startColor,
|
||
@ColorInt Integer enabled_centerColor,
|
||
@ColorInt Integer enabled_endColor,
|
||
@Orientation int enabled_orientation,
|
||
@GradientType int enabled_gradientType,
|
||
Float enabled_radialCenterX,
|
||
Float enabled_radialCenterY,
|
||
float enabled_radialRadius,
|
||
float enabled_width,
|
||
float enabled_height,
|
||
float enabled_marginLeft,
|
||
float enabled_marginTop,
|
||
float enabled_marginRight,
|
||
float enabled_marginBottom,
|
||
float enabled_ringThickness,
|
||
float enabled_ringThicknessRatio,
|
||
float enabled_ringInnerRadius,
|
||
float enabled_ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int focused_shapeMode,
|
||
@ColorInt Integer focused_solidColor,
|
||
@ColorInt int focused_strokeColor,
|
||
float focused_strokeWidth,
|
||
float focused_strokeDash,
|
||
float focused_strokeDashGap,
|
||
float focused_radius,
|
||
float focused_radiusLT,
|
||
float focused_radiusLB,
|
||
float focused_radiusRT,
|
||
float focused_radiusRB,
|
||
@ColorInt Integer focused_startColor,
|
||
@ColorInt Integer focused_centerColor,
|
||
@ColorInt Integer focused_endColor,
|
||
@Orientation int focused_orientation,
|
||
@GradientType int focused_gradientType,
|
||
Float focused_radialCenterX,
|
||
Float focused_radialCenterY,
|
||
float focused_radialRadius,
|
||
float focused_width,
|
||
float focused_height,
|
||
float focused_marginLeft,
|
||
float focused_marginTop,
|
||
float focused_marginRight,
|
||
float focused_marginBottom,
|
||
float focused_ringThickness,
|
||
float focused_ringThicknessRatio,
|
||
float focused_ringInnerRadius,
|
||
float focused_ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int pressed_shapeMode,
|
||
@ColorInt Integer pressed_solidColor,
|
||
@ColorInt int pressed_strokeColor,
|
||
float pressed_strokeWidth,
|
||
float pressed_strokeDash,
|
||
float pressed_strokeDashGap,
|
||
float pressed_radius,
|
||
float pressed_radiusLT,
|
||
float pressed_radiusLB,
|
||
float pressed_radiusRT,
|
||
float pressed_radiusRB,
|
||
@ColorInt Integer pressed_startColor,
|
||
@ColorInt Integer pressed_centerColor,
|
||
@ColorInt Integer pressed_endColor,
|
||
@Orientation int pressed_orientation,
|
||
@GradientType int pressed_gradientType,
|
||
Float pressed_radialCenterX,
|
||
Float pressed_radialCenterY,
|
||
float pressed_radialRadius,
|
||
float pressed_width,
|
||
float pressed_height,
|
||
float pressed_marginLeft,
|
||
float pressed_marginTop,
|
||
float pressed_marginRight,
|
||
float pressed_marginBottom,
|
||
float pressed_ringThickness,
|
||
float pressed_ringThicknessRatio,
|
||
float pressed_ringInnerRadius,
|
||
float pressed_ringInnerRadiusRatio,
|
||
|
||
@ShapeMode int selected_shapeMode,
|
||
@ColorInt Integer selected_solidColor,
|
||
@ColorInt int selected_strokeColor,
|
||
float selected_strokeWidth,
|
||
float selected_strokeDash,
|
||
float selected_strokeDashGap,
|
||
float selected_radius,
|
||
float selected_radiusLT,
|
||
float selected_radiusLB,
|
||
float selected_radiusRT,
|
||
float selected_radiusRB,
|
||
@ColorInt Integer selected_startColor,
|
||
@ColorInt Integer selected_centerColor,
|
||
@ColorInt Integer selected_endColor,
|
||
@Orientation int selected_orientation,
|
||
@GradientType int selected_gradientType,
|
||
Float selected_radialCenterX,
|
||
Float selected_radialCenterY,
|
||
float selected_radialRadius,
|
||
float selected_width,
|
||
float selected_height,
|
||
float selected_marginLeft,
|
||
float selected_marginTop,
|
||
float selected_marginRight,
|
||
float selected_marginBottom,
|
||
float selected_ringThickness,
|
||
float selected_ringThicknessRatio,
|
||
float selected_ringInnerRadius,
|
||
float selected_ringInnerRadiusRatio,
|
||
|
||
Drawable drawable,
|
||
Drawable drawable_checked,
|
||
Drawable drawable_checkable,
|
||
Drawable drawable_enabled,
|
||
Drawable drawable_focused,
|
||
Drawable drawable_pressed,
|
||
Drawable drawable_selected
|
||
) {
|
||
boolean isDefaultNull = false;
|
||
int count = 0;
|
||
Drawable defaultDrawable = drawable != null ? drawable : create(
|
||
shapeMode,
|
||
solidColor,
|
||
strokeColor,
|
||
strokeWidth,
|
||
strokeDash,
|
||
strokeDashGap,
|
||
radius,
|
||
radiusLT,
|
||
radiusLB,
|
||
radiusRT,
|
||
radiusRB,
|
||
startColor,
|
||
centerColor,
|
||
endColor,
|
||
orientation,
|
||
gradientType,
|
||
radialCenterX,
|
||
radialCenterY,
|
||
radialRadius,
|
||
width,
|
||
height,
|
||
marginLeft,
|
||
marginTop,
|
||
marginRight,
|
||
marginBottom,
|
||
ringThickness,
|
||
ringThicknessRatio,
|
||
ringInnerRadius,
|
||
ringInnerRadiusRatio
|
||
);
|
||
if (defaultDrawable != null) {
|
||
count++;
|
||
} else {
|
||
isDefaultNull = true;
|
||
}
|
||
Drawable checkedDrawable = drawable_checked != null ? drawable_checked : create(
|
||
checked_shapeMode,
|
||
checked_solidColor,
|
||
checked_strokeColor,
|
||
checked_strokeWidth,
|
||
checked_strokeDash,
|
||
checked_strokeDashGap,
|
||
checked_radius,
|
||
checked_radiusLT,
|
||
checked_radiusLB,
|
||
checked_radiusRT,
|
||
checked_radiusRB,
|
||
checked_startColor,
|
||
checked_centerColor,
|
||
checked_endColor,
|
||
checked_orientation,
|
||
checked_gradientType,
|
||
checked_radialCenterX,
|
||
checked_radialCenterY,
|
||
checked_radialRadius,
|
||
checked_width,
|
||
checked_height,
|
||
checked_marginLeft,
|
||
checked_marginTop,
|
||
checked_marginRight,
|
||
checked_marginBottom,
|
||
checked_ringThickness,
|
||
checked_ringThicknessRatio,
|
||
checked_ringInnerRadius,
|
||
checked_ringInnerRadiusRatio
|
||
);
|
||
if (checkedDrawable != null) {
|
||
count++;
|
||
}
|
||
Drawable checkableDrawable = drawable_checkable != null ? drawable_checkable : create(
|
||
checkable_shapeMode,
|
||
checkable_solidColor,
|
||
checkable_strokeColor,
|
||
checkable_strokeWidth,
|
||
checkable_strokeDash,
|
||
checkable_strokeDashGap,
|
||
checkable_radius,
|
||
checkable_radiusLT,
|
||
checkable_radiusLB,
|
||
checkable_radiusRT,
|
||
checkable_radiusRB,
|
||
checkable_startColor,
|
||
checkable_centerColor,
|
||
checkable_endColor,
|
||
checkable_orientation,
|
||
checkable_gradientType,
|
||
checkable_radialCenterX,
|
||
checkable_radialCenterY,
|
||
checkable_radialRadius,
|
||
checkable_width,
|
||
checkable_height,
|
||
checkable_marginLeft,
|
||
checkable_marginTop,
|
||
checkable_marginRight,
|
||
checkable_marginBottom,
|
||
checkable_ringThickness,
|
||
checkable_ringThicknessRatio,
|
||
checkable_ringInnerRadius,
|
||
checkable_ringInnerRadiusRatio
|
||
);
|
||
if (checkableDrawable != null) {
|
||
count++;
|
||
}
|
||
Drawable enabledDrawable = drawable_enabled != null ? drawable_enabled : create(
|
||
enabled_shapeMode,
|
||
enabled_solidColor,
|
||
enabled_strokeColor,
|
||
enabled_strokeWidth,
|
||
enabled_strokeDash,
|
||
enabled_strokeDashGap,
|
||
enabled_radius,
|
||
enabled_radiusLT,
|
||
enabled_radiusLB,
|
||
enabled_radiusRT,
|
||
enabled_radiusRB,
|
||
enabled_startColor,
|
||
enabled_centerColor,
|
||
enabled_endColor,
|
||
enabled_orientation,
|
||
enabled_gradientType,
|
||
enabled_radialCenterX,
|
||
enabled_radialCenterY,
|
||
enabled_radialRadius,
|
||
enabled_width,
|
||
enabled_height,
|
||
enabled_marginLeft,
|
||
enabled_marginTop,
|
||
enabled_marginRight,
|
||
enabled_marginBottom,
|
||
enabled_ringThickness,
|
||
enabled_ringThicknessRatio,
|
||
enabled_ringInnerRadius,
|
||
enabled_ringInnerRadiusRatio
|
||
);
|
||
if (enabledDrawable != null) {
|
||
count++;
|
||
}
|
||
Drawable focusedDrawable = drawable_focused != null ? drawable_focused : create(
|
||
focused_shapeMode,
|
||
focused_solidColor,
|
||
focused_strokeColor,
|
||
focused_strokeWidth,
|
||
focused_strokeDash,
|
||
focused_strokeDashGap,
|
||
focused_radius,
|
||
focused_radiusLT,
|
||
focused_radiusLB,
|
||
focused_radiusRT,
|
||
focused_radiusRB,
|
||
focused_startColor,
|
||
focused_centerColor,
|
||
focused_endColor,
|
||
focused_orientation,
|
||
focused_gradientType,
|
||
focused_radialCenterX,
|
||
focused_radialCenterY,
|
||
focused_radialRadius,
|
||
focused_width,
|
||
focused_height,
|
||
focused_marginLeft,
|
||
focused_marginTop,
|
||
focused_marginRight,
|
||
focused_marginBottom,
|
||
focused_ringThickness,
|
||
focused_ringThicknessRatio,
|
||
focused_ringInnerRadius,
|
||
focused_ringInnerRadiusRatio
|
||
);
|
||
if (focusedDrawable != null) {
|
||
count++;
|
||
}
|
||
Drawable pressedDrawable = drawable_pressed != null ? drawable_pressed : create(
|
||
pressed_shapeMode,
|
||
pressed_solidColor,
|
||
pressed_strokeColor,
|
||
pressed_strokeWidth,
|
||
pressed_strokeDash,
|
||
pressed_strokeDashGap,
|
||
pressed_radius,
|
||
pressed_radiusLT,
|
||
pressed_radiusLB,
|
||
pressed_radiusRT,
|
||
pressed_radiusRB,
|
||
pressed_startColor,
|
||
pressed_centerColor,
|
||
pressed_endColor,
|
||
pressed_orientation,
|
||
pressed_gradientType,
|
||
pressed_radialCenterX,
|
||
pressed_radialCenterY,
|
||
pressed_radialRadius,
|
||
pressed_width,
|
||
pressed_height,
|
||
pressed_marginLeft,
|
||
pressed_marginTop,
|
||
pressed_marginRight,
|
||
pressed_marginBottom,
|
||
pressed_ringThickness,
|
||
pressed_ringThicknessRatio,
|
||
pressed_ringInnerRadius,
|
||
pressed_ringInnerRadiusRatio
|
||
);
|
||
if (pressedDrawable != null) {
|
||
count++;
|
||
}
|
||
Drawable selectedDrawable = drawable_selected != null ? drawable_selected : create(
|
||
selected_shapeMode,
|
||
selected_solidColor,
|
||
selected_strokeColor,
|
||
selected_strokeWidth,
|
||
selected_strokeDash,
|
||
selected_strokeDashGap,
|
||
selected_radius,
|
||
selected_radiusLT,
|
||
selected_radiusLB,
|
||
selected_radiusRT,
|
||
selected_radiusRB,
|
||
selected_startColor,
|
||
selected_centerColor,
|
||
selected_endColor,
|
||
selected_orientation,
|
||
selected_gradientType,
|
||
selected_radialCenterX,
|
||
selected_radialCenterY,
|
||
selected_radialRadius,
|
||
selected_width,
|
||
selected_height,
|
||
selected_marginLeft,
|
||
selected_marginTop,
|
||
selected_marginRight,
|
||
selected_marginBottom,
|
||
selected_ringThickness,
|
||
selected_ringThicknessRatio,
|
||
selected_ringInnerRadius,
|
||
selected_ringInnerRadiusRatio
|
||
);
|
||
if (selectedDrawable != null) {
|
||
count++;
|
||
}
|
||
//noinspection StatementWithEmptyBody
|
||
if (count < 1) {
|
||
// impossible,因为该方法被调用说明至少声明了一条属性
|
||
} else {
|
||
boolean needReSetPadding = false;
|
||
if (isDefaultNull || count == 1) {
|
||
// 当设置了margin(非view的margin)时,InsetDrawable会导致view本身的padding失效
|
||
needReSetPadding = true;
|
||
TMP_PADDING[0] = view.getPaddingLeft();
|
||
TMP_PADDING[1] = view.getPaddingTop();
|
||
TMP_PADDING[2] = view.getPaddingRight();
|
||
TMP_PADDING[3] = view.getPaddingBottom();
|
||
}
|
||
if (count == 1 && !isDefaultNull) {
|
||
view.setBackground(defaultDrawable);
|
||
} else {
|
||
ProxyDrawable listDrawable = new ProxyDrawable();
|
||
if (checkedDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_checked}, checkedDrawable);
|
||
}
|
||
if (checkableDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_checkable}, checkableDrawable);
|
||
}
|
||
if (enabledDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_enabled}, enabledDrawable);
|
||
}
|
||
if (focusedDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_focused}, focusedDrawable);
|
||
}
|
||
if (pressedDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);
|
||
}
|
||
if (selectedDrawable != null) {
|
||
listDrawable.addState(new int[]{android.R.attr.state_selected}, selectedDrawable);
|
||
}
|
||
if (defaultDrawable != null) {
|
||
listDrawable.addState(new int[]{0}, defaultDrawable);
|
||
} else {
|
||
Drawable originDrawable = view.getBackground();
|
||
if (originDrawable != null) {
|
||
if (originDrawable instanceof ProxyDrawable) {
|
||
originDrawable = ((ProxyDrawable) originDrawable).getOriginDrawable();
|
||
}
|
||
listDrawable.addState(new int[]{0}, originDrawable);
|
||
}
|
||
}
|
||
view.setBackground(listDrawable);
|
||
}
|
||
if (needReSetPadding) {
|
||
view.setPadding(TMP_PADDING[0], TMP_PADDING[1], TMP_PADDING[2], TMP_PADDING[3]);
|
||
}
|
||
}
|
||
}
|
||
|
||
public static Drawable create(
|
||
@ShapeMode int shapeMode, @ColorInt Integer solidColor,
|
||
@ColorInt int strokeColor, @DP float strokeWidth, @DP float strokeDash, @DP float strokeDashGap,
|
||
@DP float radius, @DP float radiusLT, @DP float radiusLB, @DP float radiusRT, @DP float radiusRB,
|
||
@ColorInt Integer startColor, @ColorInt Integer centerColor, @ColorInt Integer endColor,
|
||
@Orientation int orientation, @GradientType int gradientType,
|
||
Float radialCenterX, Float radialCenterY, float radialRadius,
|
||
@DP float width, @DP float height,
|
||
@DP float marginLeft, @DP float marginTop, @DP float marginRight, @DP float marginBottom,
|
||
@DP float ringThickness,
|
||
@DP float ringThicknessRatio,
|
||
@DP float ringInnerRadius,
|
||
@DP float ringInnerRadiusRatio
|
||
) {
|
||
if (shapeMode == INVALID && solidColor == null && strokeColor == INVALID
|
||
&& strokeWidth == INVALID && strokeDash == INVALID && strokeDashGap == INVALID
|
||
&& radius == INVALID && radiusLT == INVALID && radiusLB == INVALID
|
||
&& radiusRT == INVALID && radiusRB == INVALID && startColor == null
|
||
&& centerColor == null && endColor == null && orientation == INVALID
|
||
&& gradientType == INVALID && radialCenterX == null && radialCenterY == null
|
||
&& radialRadius == INVALID && width == INVALID && height == INVALID
|
||
&& marginLeft == INVALID && marginTop == INVALID && marginRight == INVALID && marginBottom == INVALID
|
||
) {
|
||
// 这里需要判断empty,因为有可能只设置了一个state的drawable,那么其他state的就是empty了
|
||
return null;
|
||
}
|
||
GradientDrawable drawable = new GradientDrawable();
|
||
if (startColor != null && endColor != null) {
|
||
int[] colors;
|
||
if (centerColor != null) {
|
||
colors = new int[3];
|
||
colors[0] = startColor;
|
||
colors[1] = centerColor;
|
||
colors[2] = endColor;
|
||
} else {
|
||
colors = new int[2];
|
||
colors[0] = startColor;
|
||
colors[1] = endColor;
|
||
}
|
||
drawable.setColors(colors);
|
||
drawable.setOrientation(mapOrientation(orientation));
|
||
drawable.setGradientType(gradientType);
|
||
if (gradientType == GradientType.RADIAL) {
|
||
drawable.setGradientCenter(radialCenterX == null ? .5f : radialCenterX,
|
||
radialCenterY == null ? .5f : radialCenterY);
|
||
drawable.setGradientRadius(dip2px(radialRadius));
|
||
}
|
||
} else {
|
||
if (solidColor != null) {
|
||
drawable.setColor(solidColor);
|
||
}
|
||
}
|
||
drawable.setShape(validShapeMode(shapeMode));
|
||
if (shapeMode == ShapeMode.RING) {
|
||
// 由于GradientDrawable中没有ring相关的公开API,所以使用反射,若对性能有要求,请注意。
|
||
setRingValue(drawable, ringThickness, ringThicknessRatio, ringInnerRadius, ringInnerRadiusRatio);
|
||
}
|
||
if (strokeWidth > 0) {
|
||
drawable.setStroke(dip2px(strokeWidth), strokeColor, dip2px(strokeDash), dip2px(strokeDashGap));
|
||
}
|
||
if (radius <= 0) {
|
||
float[] radiusEach = new float[]{dip2px(radiusLT), dip2px(radiusLT), dip2px(radiusRT), dip2px(radiusRT),
|
||
dip2px(radiusRB), dip2px(radiusRB), dip2px(radiusLB), dip2px(radiusLB)};
|
||
drawable.setCornerRadii(radiusEach);
|
||
} else {
|
||
drawable.setCornerRadius(dip2px(radius));
|
||
}
|
||
if (width > 0 && height > 0) {
|
||
// https://stackoverflow.com/a/29180660/4698946
|
||
drawable.setSize(dip2px(width), dip2px(height));
|
||
}
|
||
if (marginLeft != 0 || marginTop != 0 || marginRight != 0 || marginBottom != 0) {
|
||
return new InsetDrawable(drawable,
|
||
dip2px(marginLeft),
|
||
dip2px(marginTop),
|
||
dip2px(marginRight),
|
||
dip2px(marginBottom));
|
||
} else {
|
||
return drawable;
|
||
}
|
||
}
|
||
|
||
private static int validShapeMode(@ShapeMode int shapeMode) {
|
||
return shapeMode > ShapeMode.RING || shapeMode < ShapeMode.RECTANGLE
|
||
? GradientDrawable.RECTANGLE : shapeMode;
|
||
}
|
||
|
||
private static GradientDrawable.Orientation mapOrientation(@Orientation int orientation) {
|
||
switch (orientation) {
|
||
case Orientation.BL_TR:
|
||
return GradientDrawable.Orientation.BL_TR;
|
||
case Orientation.BOTTOM_TOP:
|
||
return GradientDrawable.Orientation.BOTTOM_TOP;
|
||
case Orientation.BR_TL:
|
||
return GradientDrawable.Orientation.BR_TL;
|
||
case Orientation.LEFT_RIGHT:
|
||
return GradientDrawable.Orientation.LEFT_RIGHT;
|
||
case Orientation.RIGHT_LEFT:
|
||
return GradientDrawable.Orientation.RIGHT_LEFT;
|
||
case Orientation.TL_BR:
|
||
return GradientDrawable.Orientation.TL_BR;
|
||
case Orientation.TOP_BOTTOM:
|
||
return GradientDrawable.Orientation.TOP_BOTTOM;
|
||
case Orientation.TR_BL:
|
||
return GradientDrawable.Orientation.TR_BL;
|
||
default:
|
||
break;
|
||
}
|
||
return GradientDrawable.Orientation.TOP_BOTTOM;
|
||
}
|
||
|
||
private static void setRingValue(GradientDrawable drawable,
|
||
Float thickness, Float thicknessRatio,
|
||
Float innerRadius, Float innerRadiusRatio) {
|
||
try {
|
||
Field mGradientState = drawable.getClass().getDeclaredField("mGradientState");
|
||
mGradientState.setAccessible(true);
|
||
Class mGradientStateClass = mGradientState.get(drawable).getClass();
|
||
Field mUseLevelForShape = mGradientStateClass.getDeclaredField("mUseLevelForShape");
|
||
mUseLevelForShape.setAccessible(true);
|
||
mUseLevelForShape.setBoolean(mGradientState.get(drawable), false);
|
||
if (thickness != null) {
|
||
Field mThickness = mGradientStateClass.getDeclaredField("mThickness");
|
||
mThickness.setAccessible(true);
|
||
mThickness.setInt(mGradientState.get(drawable), dip2px(thickness));
|
||
}
|
||
if (thicknessRatio != null) {
|
||
Field mThicknessRatio = mGradientStateClass.getDeclaredField("mThicknessRatio");
|
||
mThicknessRatio.setAccessible(true);
|
||
mThicknessRatio.setFloat(mGradientState.get(drawable), dip2px(thicknessRatio));
|
||
}
|
||
if (innerRadius != null) {
|
||
Field mInnerRadius = mGradientStateClass.getDeclaredField("mInnerRadius");
|
||
mInnerRadius.setAccessible(true);
|
||
mInnerRadius.setInt(mGradientState.get(drawable), dip2px(innerRadius));
|
||
}
|
||
if (innerRadiusRatio != null) {
|
||
Field mInnerRadiusRatio = mGradientStateClass.getDeclaredField("mInnerRadiusRatio");
|
||
mInnerRadiusRatio.setAccessible(true);
|
||
mInnerRadiusRatio.setFloat(mGradientState.get(drawable), dip2px(innerRadiusRatio));
|
||
}
|
||
} catch (NoSuchFieldException | IllegalAccessException t) {
|
||
t.printStackTrace();
|
||
}
|
||
}
|
||
|
||
private static int dip2px(float dipValue) {
|
||
final float scale = Resources.getSystem().getDisplayMetrics().density;
|
||
return (int) (dipValue * scale + .5f);
|
||
}
|
||
|
||
|
||
@IntDef({
|
||
ShapeMode.RECTANGLE,
|
||
ShapeMode.OVAL,
|
||
ShapeMode.LINE,
|
||
ShapeMode.RING,
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface ShapeMode {
|
||
int RECTANGLE = GradientDrawable.RECTANGLE;
|
||
int OVAL = GradientDrawable.OVAL;
|
||
/**
|
||
* 画线时,有几点特性必须要知道的:
|
||
* 1. 只能画水平线,画不了竖线;
|
||
* 2. 线的高度是通过stroke的android:width属性设置的;
|
||
* 3. size的android:height属性定义的是整个形状区域的高度;
|
||
* 4. size的height必须大于stroke的width,否则,线无法显示;
|
||
* 5. 线在整个形状区域中是居中显示的;
|
||
* 6. 线左右两边会留有空白间距,线越粗,空白越大;
|
||
* 7. 引用虚线的view需要添加属性android:layerType,值设为"software",否则显示不了虚线。
|
||
*/
|
||
int LINE = GradientDrawable.LINE;
|
||
int RING = GradientDrawable.RING;
|
||
}
|
||
|
||
@IntDef({
|
||
GradientType.LINEAR,
|
||
GradientType.RADIAL,
|
||
GradientType.SWEEP
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface GradientType {
|
||
int LINEAR = 0;
|
||
int RADIAL = 1;
|
||
int SWEEP = 2;
|
||
}
|
||
|
||
@IntDef({
|
||
Orientation.TOP_BOTTOM,
|
||
Orientation.TR_BL,
|
||
Orientation.RIGHT_LEFT,
|
||
Orientation.BR_TL,
|
||
Orientation.BOTTOM_TOP,
|
||
Orientation.BL_TR,
|
||
Orientation.LEFT_RIGHT,
|
||
Orientation.TL_BR
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface Orientation {
|
||
int TOP_BOTTOM = 0;
|
||
int TR_BL = 1;
|
||
int RIGHT_LEFT = 2;
|
||
int BR_TL = 3;
|
||
int BOTTOM_TOP = 4;
|
||
int BL_TR = 5;
|
||
int LEFT_RIGHT = 6;
|
||
int TL_BR = 7;
|
||
}
|
||
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
@Target({PARAMETER, FIELD})
|
||
@interface DP {
|
||
}
|
||
|
||
public static class ProxyDrawable extends StateListDrawable {
|
||
|
||
private Drawable originDrawable;
|
||
|
||
@Override
|
||
public void addState(int[] stateSet, Drawable drawable) {
|
||
if (stateSet != null && stateSet.length == 1 && stateSet[0] == 0) {
|
||
originDrawable = drawable;
|
||
}
|
||
super.addState(stateSet, drawable);
|
||
}
|
||
|
||
Drawable getOriginDrawable() {
|
||
return originDrawable;
|
||
}
|
||
}
|
||
}
|