This is how I did it (essentially creating a custom Drawable from program code).
It gets a Drawable, tiles it (repeating it) and crops it to a shape that was provided by the Callable. It handles AnimationDrawable also: creates a similar AnimationDrawable tiling and cropping each frame. For the clip shape I had to use Callable - which is essentially a factory - because a new ShapeDrawable has to be created for each animation frame. The inner class EquallyRoundCornerRect can be used for the most common scenario: equal round corner.
/** * It gets a {@link android.graphics.drawable.Drawable}, tiles it (repeating it) and crops it to a shape that was provided by the * {@link java.util.concurrent.Callable}. It handles {@link android.graphics.drawable.AnimationDrawable} also: creates a similar * {@link android.graphics.drawable.AnimationDrawable} tiling and cropping each frame. For the clip shape I had to use * {@link java.util.concurrent.Callable} - which is essentially a factory - because a new {@link android.graphics.drawable.ShapeDrawable} * has to be created for each animation frame. * The inner class {@link EquallyRoundCornerRect} can be used for the most common scenario: equal round corner. */ public class TiledClippedDrawable { public static Drawable createFrom(final Drawable originalDrawable, final Callable<ShapeDrawable> clipShape) { return tileifyIndeterminate(originalDrawable, clipShape); } private static Drawable tileify(Drawable drawable, final Callable<ShapeDrawable> clipShape) { final Bitmap tileBitmap = ((BitmapDrawable) drawable).getBitmap(); try { final ShapeDrawable shapeDrawable = clipShape.call(); final BitmapShader bitmapShader = new BitmapShader(tileBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); shapeDrawable.getPaint().setShader(bitmapShader); return new ClipDrawable(shapeDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); } catch (Exception e) { throw new RuntimeException(e); } } private static Drawable tileifyIndeterminate(Drawable drawable, final Callable<ShapeDrawable> clipShape) { if (drawable instanceof AnimationDrawable) { AnimationDrawable background = (AnimationDrawable) drawable; final int N = background.getNumberOfFrames(); AnimationDrawable newBg = new AnimationDrawable(); newBg.setOneShot(background.isOneShot()); for (int i = 0; i < N; i++) { Drawable frame = tileify(background.getFrame(i), clipShape); frame.setLevel(10000); newBg.addFrame(frame, background.getDuration(i)); } newBg.setLevel(10000); drawable = newBg; return drawable; } return tileify(drawable, clipShape); } public static class EquallyRoundCornerRect implements Callable<ShapeDrawable> { private final int cornerRadiusPixel; public EquallyRoundCornerRect(final int cornerRadiusPixel) { this.cornerRadiusPixel = cornerRadiusPixel; } @Override public ShapeDrawable call() throws Exception { final float[] roundedCorners = new float[] {cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel, cornerRadiusPixel}; return new ShapeDrawable(new RoundRectShape(roundedCorners, null, null)); } } }
And this is how it can be used:
final int cornerRadius = getResources().getDimensionPixelOffset(R.dimen.progressbar_corner_radius); final Drawable originalDrawable = getResources().getDrawable(R.drawable.progress_bar_indeterminate_horizontal); final Drawable roundedAnimation = TiledClippedDrawable.createFrom(originalDrawable, new TiledClippedDrawable.EquallyRoundCornerRect(cornerRadius)); unpackingSpinner = (ProgressBar) backView.findViewById(R.id.gallery_item_unpacking_spinner); unpackingSpinner.setIndeterminateDrawable(roundedAnimation);
Here the R.dimen.progressbar_corner_radius is a number, and the R.drawable.progress_bar_indeterminate_horizontal is an animationlist. Each of those install_progressbar_indeterminate1 images contain only a fragment, because they will be tiled anyway.
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/install_progressbar_indeterminate1" android:duration="200" /> <item android:drawable="@drawable/install_progressbar_indeterminate2" android:duration="200" /> <item android:drawable="@drawable/install_progressbar_indeterminate3" android:duration="200" /> </animation-list>
No comments:
Post a Comment