下面列出了怎么用android.graphics.drawable.DrawableContainer的API类实例代码及写法,或者点击链接到github查看源代码。
public static boolean containsNinePatch(Drawable drawable) {
drawable = getWrapperDrawable(drawable);
if (drawable instanceof NinePatchDrawable || drawable instanceof InsetDrawable || drawable instanceof LayerDrawable) {
return true;
} else if (drawable instanceof StateListDrawable) {
final DrawableContainer.DrawableContainerState containerState = ((DrawableContainer.DrawableContainerState) drawable.getConstantState());
//can't get containState from drawable which is containing DrawableWrapperDonut
//https://code.google.com/p/android/issues/detail?id=169920
if (containerState == null) {
return true;
}
for (Drawable dr : containerState.getChildren()) {
dr = getWrapperDrawable(dr);
if (dr instanceof NinePatchDrawable || dr instanceof InsetDrawable || dr instanceof LayerDrawable) {
return true;
}
}
}
return false;
}
public static boolean canSafelyMutateDrawable(@NonNull Drawable drawable) {
if (drawable instanceof DrawableContainer) {
// If we have a DrawableContainer, let's traverse it's child array
final Drawable.ConstantState state = drawable.getConstantState();
if (state instanceof DrawableContainer.DrawableContainerState) {
final DrawableContainer.DrawableContainerState containerState =
(DrawableContainer.DrawableContainerState) state;
for (final Drawable child : containerState.getChildren()) {
if (!canSafelyMutateDrawable(child)) {
return false;
}
}
}
} else if (drawable instanceof DrawableWrapper) {
return canSafelyMutateDrawable(
Objects.requireNonNull(((DrawableWrapper) drawable).getDrawable()));
} else if (drawable instanceof ScaleDrawable) {
return canSafelyMutateDrawable(Objects.requireNonNull(((ScaleDrawable) drawable).getDrawable()));
}
return true;
}
public static boolean containsNinePatch(Drawable drawable) {
drawable = getWrapperDrawable(drawable);
if (drawable instanceof NinePatchDrawable
|| drawable instanceof InsetDrawable
|| drawable instanceof LayerDrawable) {
return true;
} else if (drawable instanceof StateListDrawable) {
final DrawableContainer.DrawableContainerState containerState = ((DrawableContainer.DrawableContainerState) drawable.getConstantState());
//can't get containState from drawable which is containing DrawableWrapperDonut
//https://code.google.com/p/android/issues/detail?id=169920
if (containerState == null) {
return true;
}
for (Drawable dr : containerState.getChildren()) {
dr = getWrapperDrawable(dr);
if (dr instanceof NinePatchDrawable
|| dr instanceof InsetDrawable
|| dr instanceof LayerDrawable) {
return true;
}
}
}
return false;
}
private static boolean shouldMutateBackground(Drawable drawable) {
if (Build.VERSION.SDK_INT >= 16) {
// For SDK 16+, we should be fine mutating the drawable
return true;
}
if (drawable instanceof LayerDrawable) {
return Build.VERSION.SDK_INT >= 16;
} else if (drawable instanceof InsetDrawable) {
return Build.VERSION.SDK_INT >= 14;
} else if (drawable instanceof DrawableContainer) {
// If we have a DrawableContainer, let's traverse it's child array
final Drawable.ConstantState state = drawable.getConstantState();
if (state instanceof DrawableContainer.DrawableContainerState) {
final DrawableContainer.DrawableContainerState containerState =
(DrawableContainer.DrawableContainerState) state;
for (Drawable child : containerState.getChildren()) {
if (!shouldMutateBackground(child)) {
return false;
}
}
}
}
return true;
}
/**
* Check if two Drawables are equal. A regular check for a Drawable equals
* just checks for the instance reference, while this check is doing a
* deeper equals when dealing with {@link DrawableContainer} instances. In
* these cases, the method will run equals on each of the child drawables in
* the container (order is importance as well).
*
* @param d1
* @param d2
* @return <code>true</code> if the drawables are equal, <code>false</code>
* otherwise.
*/
public static boolean isEquals(Drawable d1, Drawable d2) {
if (d1 == d2) {
return true;
}
if (d1 == null || d2 == null) {
return false;
}
if (d1 instanceof DrawableContainer && d2 instanceof DrawableContainer) {
// Try to match the content of those containers
DrawableContainerState containerState1 = (DrawableContainerState) ((DrawableContainer) d1)
.getConstantState();
DrawableContainerState containerState2 = (DrawableContainerState) ((DrawableContainer) d2)
.getConstantState();
return Arrays.equals(containerState1.getChildren(), containerState2.getChildren());
}
return d1.equals(d2);
}
/**
* Some drawable implementations have problems with mutation. This method returns false if
* there is a known issue in the given drawable's implementation.
*/
public static boolean canSafelyMutateDrawable(@NonNull Drawable drawable) {
if (Build.VERSION.SDK_INT < 15 && drawable instanceof InsetDrawable) {
return false;
} else if (Build.VERSION.SDK_INT < 15 && drawable instanceof GradientDrawable) {
// GradientDrawable has a bug pre-ICS which results in mutate() resulting
// in loss of color
return false;
} else if (Build.VERSION.SDK_INT < 17 && drawable instanceof LayerDrawable) {
return false;
}
if (drawable instanceof DrawableContainer) {
// If we have a DrawableContainer, let's traverse it's child array
final Drawable.ConstantState state = drawable.getConstantState();
if (state instanceof DrawableContainer.DrawableContainerState) {
final DrawableContainer.DrawableContainerState containerState =
(DrawableContainer.DrawableContainerState) state;
for (final Drawable child : containerState.getChildren()) {
if (!canSafelyMutateDrawable(child)) {
return false;
}
}
}
} else if (SkinCompatVersionUtils.isV4DrawableWrapper(drawable)) {
return canSafelyMutateDrawable(SkinCompatVersionUtils.getV4DrawableWrapperWrappedDrawable(drawable));
} else if (SkinCompatVersionUtils.isV4WrappedDrawable(drawable)) {
return canSafelyMutateDrawable(SkinCompatVersionUtils.getV4WrappedDrawableWrappedDrawable(drawable));
} else if (SkinCompatVersionUtils.isV7DrawableWrapper(drawable)) {
return canSafelyMutateDrawable(SkinCompatVersionUtils.getV7DrawableWrapperWrappedDrawable(drawable));
} else if (drawable instanceof ScaleDrawable) {
Drawable scaleDrawable = ((ScaleDrawable) drawable).getDrawable();
if (scaleDrawable != null) {
return canSafelyMutateDrawable(scaleDrawable);
}
}
return true;
}
/**
* Some drawable implementations have problems with mutation. This method returns false if
* there is a known issue in the given drawable's implementation.
*/
public static boolean canSafelyMutateDrawable(@NonNull Drawable drawable) {
if (Build.VERSION.SDK_INT < 15 && drawable instanceof InsetDrawable) {
return false;
} else if (Build.VERSION.SDK_INT < 15 && drawable instanceof GradientDrawable) {
// GradientDrawable has a bug pre-ICS which results in mutate() resulting
// in loss of color
return false;
} else if (Build.VERSION.SDK_INT < 17 && drawable instanceof LayerDrawable) {
return false;
}
if (drawable instanceof DrawableContainer) {
// If we have a DrawableContainer, let's traverse it's child array
final Drawable.ConstantState state = drawable.getConstantState();
if (state instanceof DrawableContainer.DrawableContainerState) {
final DrawableContainer.DrawableContainerState containerState =
(DrawableContainer.DrawableContainerState) state;
for (final Drawable child : containerState.getChildren()) {
if (!canSafelyMutateDrawable(child)) {
return false;
}
}
}
} else if (SkinCompatVersionUtils.isV4DrawableWrapper(drawable)) {
return canSafelyMutateDrawable(SkinCompatVersionUtils.getV4DrawableWrapperWrappedDrawable(drawable));
} else if (SkinCompatVersionUtils.isV4WrappedDrawable(drawable)) {
return canSafelyMutateDrawable(SkinCompatVersionUtils.getV4WrappedDrawableWrappedDrawable(drawable));
} else if (drawable instanceof DrawableWrapper) {
return canSafelyMutateDrawable(((DrawableWrapper) drawable).getWrappedDrawable());
} else if (drawable instanceof ScaleDrawable) {
return canSafelyMutateDrawable(((ScaleDrawable) drawable).getDrawable());
}
return true;
}
private static Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof DrawableContainer) {
return getBitmapFromDrawable(drawable.getCurrent());
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
} else {
return null;
}
}
@Override
public boolean updateStyle(List<PXRuleSet> ruleSets, List<PXStylerContext> contexts) {
if (!super.updateStyle(ruleSets, contexts)) {
return false;
}
// Extract the existing compound icons
TextView styleable = (TextView) contexts.get(0).getStyleable();
Drawable[] compoundDrawables = styleable.getCompoundDrawables();
Drawable iconDrawable = compoundDrawables[position.ordinal()];
Map<int[], Drawable> existingStates = PXDrawableUtil.getExistingStates(iconDrawable);
Drawable newDrawable = null;
if (existingStates == null || existingStates.isEmpty()) {
// create a new StateListDrawable for that icon with the original
// style adapter
if (contexts.size() == 1) {
newDrawable = contexts.get(0).getBackgroundImage();
} else {
newDrawable = PXDrawableUtil.createNewStateListDrawable(
PXStyleAdapter.getStyleAdapter(styleable), ruleSets, contexts);
}
} else {
// create a drawable that will hold a merge of the existing states
// and the new states.
newDrawable = PXDrawableUtil.createDrawable(
PXStyleAdapter.getStyleAdapter(styleable), existingStates, ruleSets, contexts);
}
// Set the drawable.
if (newDrawable != null
&& !PXDrawableUtil.isEquals(newDrawable, compoundDrawables[position.ordinal()])) {
compoundDrawables[position.ordinal()] = newDrawable;
if (newDrawable instanceof DrawableContainer && newDrawable.getCurrent() == null) {
// We have to select a Drawable in the StateListDrawables.
// Otherwise, the bounds will not be set correctly.
DrawableContainer container = (DrawableContainer) newDrawable;
container.selectDrawable(0);
}
newDrawable.setBounds(0, 0, newDrawable.getIntrinsicWidth(),
newDrawable.getIntrinsicHeight());
styleable.setCompoundDrawables(compoundDrawables[0], compoundDrawables[1],
compoundDrawables[2], compoundDrawables[3]);
}
return true;
}