-
-
Save harrane/815e8a94d7ca75d964714228af69c60c to your computer and use it in GitHub Desktop.
| import android.content.Context; | |
| import android.graphics.Bitmap; | |
| import android.graphics.BitmapShader; | |
| import android.graphics.Canvas; | |
| import android.graphics.PorterDuff; | |
| import android.graphics.Shader; | |
| import android.graphics.drawable.BitmapDrawable; | |
| import android.graphics.drawable.ClipDrawable; | |
| import android.graphics.drawable.Drawable; | |
| import android.graphics.drawable.LayerDrawable; | |
| import android.graphics.drawable.ShapeDrawable; | |
| import android.graphics.drawable.shapes.RoundRectShape; | |
| import android.graphics.drawable.shapes.Shape; | |
| import android.support.v4.graphics.drawable.DrawableWrapper; | |
| import android.support.v4.view.ViewCompat; | |
| import android.util.AttributeSet; | |
| import android.view.Gravity; | |
| import android.widget.RatingBar; | |
| public class RatingBarVectorFix extends RatingBar { | |
| private Bitmap mSampleTile; | |
| public RatingBarVectorFix(Context context) { | |
| this(context, null); | |
| } | |
| public RatingBarVectorFix(Context context, AttributeSet attrs) { | |
| this(context, attrs, android.support.v7.appcompat.R.attr.ratingBarStyle); | |
| } | |
| public RatingBarVectorFix(Context context, AttributeSet attrs, int defStyleAttr) { | |
| super(context, attrs, defStyleAttr); | |
| init(); | |
| } | |
| private void init() { | |
| LayerDrawable drawable = (LayerDrawable) tileify(getProgressDrawable(), false); | |
| drawable.findDrawableByLayerId(android.R.id.background).setColorFilter(backgroundTintColor, PorterDuff.Mode.SRC_ATOP); | |
| drawable.findDrawableByLayerId(android.R.id.progress).setColorFilter(progressTintColor, PorterDuff.Mode.SRC_ATOP); | |
| setProgressDrawable(drawable); | |
| } | |
| /** | |
| * Converts a drawable to a tiled version of itself. It will recursively | |
| * traverse layer and state list drawables. | |
| */ | |
| private Drawable tileify(Drawable drawable, boolean clip) { | |
| if (drawable instanceof DrawableWrapper) { | |
| Drawable inner = ((DrawableWrapper) drawable).getWrappedDrawable(); | |
| if (inner != null) { | |
| inner = tileify(inner, clip); | |
| ((DrawableWrapper) drawable).setWrappedDrawable(inner); | |
| } | |
| } else if (drawable instanceof LayerDrawable) { | |
| LayerDrawable background = (LayerDrawable) drawable; | |
| final int N = background.getNumberOfLayers(); | |
| Drawable[] outDrawables = new Drawable[N]; | |
| for (int i = 0; i < N; i++) { | |
| int id = background.getId(i); | |
| outDrawables[i] = tileify(background.getDrawable(i), | |
| (id == android.R.id.progress || id == android.R.id.secondaryProgress)); | |
| } | |
| LayerDrawable newBg = new LayerDrawable(outDrawables); | |
| for (int i = 0; i < N; i++) { | |
| newBg.setId(i, background.getId(i)); | |
| } | |
| return newBg; | |
| } else if (drawable instanceof BitmapDrawable) { | |
| final BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; | |
| final Bitmap tileBitmap = bitmapDrawable.getBitmap(); | |
| if (mSampleTile == null) { | |
| mSampleTile = tileBitmap; | |
| } | |
| final ShapeDrawable shapeDrawable = new ShapeDrawable(getDrawableShape()); | |
| final BitmapShader bitmapShader = new BitmapShader(tileBitmap, | |
| Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); | |
| shapeDrawable.getPaint().setShader(bitmapShader); | |
| shapeDrawable.getPaint().setColorFilter(bitmapDrawable.getPaint().getColorFilter()); | |
| return (clip) ? new ClipDrawable(shapeDrawable, Gravity.LEFT, | |
| ClipDrawable.HORIZONTAL) : shapeDrawable; | |
| } else { | |
| return tileify(getBitmapDrawableFromVectorDrawable(drawable), clip); | |
| } | |
| return drawable; | |
| } | |
| private BitmapDrawable getBitmapDrawableFromVectorDrawable(Drawable drawable) { | |
| Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); | |
| Canvas canvas = new Canvas(bitmap); | |
| drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); | |
| drawable.draw(canvas); | |
| return new BitmapDrawable(getResources(), bitmap); | |
| } | |
| @Override | |
| protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
| super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
| if (mSampleTile != null) { | |
| final int width = mSampleTile.getWidth() * getNumStars(); | |
| setMeasuredDimension(ViewCompat.resolveSizeAndState(width, widthMeasureSpec, 0), | |
| getMeasuredHeight()); | |
| } | |
| } | |
| private Shape getDrawableShape() { | |
| final float[] roundedCorners = new float[]{5, 5, 5, 5, 5, 5, 5, 5}; | |
| return new RoundRectShape(roundedCorners, null, null); | |
| } | |
| } |
its not working ...
the rating is wrong.when i choose 5 , it shows only 4 stars... like that
Thanks to @darzul and it works after this change.
Also I comment these 2 lines
drawable.findDrawableByLayerId(android.R.id.background).setColorFilter(backgroundTintColor, PorterDuff.Mode.SRC_ATOP);
drawable.findDrawableByLayerId(android.R.id.progress).setColorFilter(progressTintColor, PorterDuff.Mode.SRC_ATOP);
to respect the color defined in svg xml .
I have also commented these two lines, but the rating is wrong, it selects different number of stars than it should.
For example I select 3 stars, it will select 5 sometimes or if I select 2, it will show 3 or 4 are selected..
drawable.findDrawableByLayerId(android.R.id.background).setColorFilter(backgroundTintColor, PorterDuff.Mode.SRC_ATOP);
drawable.findDrawableByLayerId(android.R.id.progress).setColorFilter(progressTintColor, PorterDuff.Mode.SRC_ATOP);
gonna crash if the progressDrawble is LayerDrawable and it layer have one instance of StateListDrawable
I've crash with SDK < 21.
I replaced
by
And it works :)
Thanks for the gist !