Skip to content

Instantly share code, notes, and snippets.

@pyricau
Created July 10, 2012 08:02
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save pyricau/3081947 to your computer and use it in GitHub Desktop.
Save pyricau/3081947 to your computer and use it in GitHub Desktop.
Android Repeated Texture Fix
public class DrawableUtils {
/**
* @see #fixTexturesInLayerDrawable(Drawable)
*/
public static void fixBackgroundTextures(View view) {
fixTexturesInLayerDrawable(view.getBackground());
}
/**
* <p>
* This will go through {@link LayerDrawable}s and all their children marked
* with {@link R.id#textureRepeat}, trying to find {@link BitmapDrawable}
* children and then setting them to a repeat {@link TileMode}.<br >
*
* <p>
* Usage in XML:
*
* <p>
* <code>
* &lt;layer-list&gt;
* &lt;item android:id="@+id/textureRepeat"&gt;
* &lt;bitmap
* android:src="@drawable/some_texture"
* android:tileMode="repeat" /&gt;
* &lt;/item&gt;
* &lt;/layer-list&gt;
*
* </code>
*
* <p>
* This is a workaround for http://b.android.com/15340, based on
* http://stackoverflow.com/a/5852198/132047
*
* <p>
* Repeated bitmap drawables have bugs pre Android 4.0 in some cases, which
* causes the texture to stretch instead of repeat.
*
* <p>
* This fix doesn't work with {@link StateListDrawable}s. For such
* drawables, you'll need manual addition of the states that hold texture
*/
public static void fixTexturesInLayerDrawable(Drawable drawable) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
if (drawable instanceof LayerDrawable) {
LayerDrawable layer = (LayerDrawable) drawable;
for (int i = 0; i < layer.getNumberOfLayers(); i++) {
if (layer.getId(i) == R.id.textureRepeat) {
fixTexturesInLayerDrawable(layer.getDrawable(i));
}
}
} else if (drawable instanceof BitmapDrawable) {
fixRepeatableBitmapDrawable((BitmapDrawable) drawable);
} else {
if (BuildConfig.DEBUG) {
throw new UnsupportedOperationException("Can only fix BitmapDrawable and layer items in LayerDrawable, not " + drawable.getClass().getName());
}
}
}
}
public static void fixRepeatableBitmapDrawable(BitmapDrawable drawable) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
drawable.mutate();
drawable.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);
}
}
/**
* Manual fix of {@link R.drawable#my_button_background_selector}
*
* See {@link #fixTexturesInLayerDrawable(Drawable)}
*/
public static void fixMyButtonBackgroundSelector(View view) {
StateListDrawable stateListDrawable = (StateListDrawable) view.getBackground();
int[] selectedStateSet = { android.R.attr.state_selected };
Drawable selectedDrawable = view.getContext().getResources().getDrawable(R.drawable.my_button_background_selected);
fixTexturesInLayerDrawable(selectedDrawable);
stateListDrawable.addState(selectedStateSet, selectedDrawable);
int[] defaultStateSet = {};
Drawable defaultDrawable = view.getContext().getResources().getDrawable(R.drawable.my_button_background_default);
fixTexturesInLayerDrawable(defaultDrawable);
stateListDrawable.addState(defaultStateSet, defaultDrawable);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment