2015-11-30 14 views
20

RatingBar in Android è frustrante.RatingBar Drawable vettoriali personalizzati sovrapposti

Ho seguito https://stackoverflow.com/a/13107765 per implementare una barra di valutazione personalizzata con i miei drawable personali, ma tutte le stelle si sovrappongono l'una all'altra, in modo che solo una singola stella venga infine visualizzata.

Non riesco, per la vita di me, a capire perché.

EDIT: drawable PNG sembrano funzionare bene, tuttavia SVG utilizzati come drawable vettore stanno causando questo problema

+0

stavo usando SVG come drawable vettoriali per le stelle vuote e piene, ma poi quando ho provato drawable PNG, ha funzionato bene. C'è qualche problema con il modo in cui Studio sta gestendo SVG allora. –

+2

Questo è un bug, ecco il problema: https://code.google.com/p/android/issues/detail?id=196713&q=vector%20ratingbar&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened –

+0

Sei riuscito a utilizzare correttamente la risposta di @ harrane qui sotto? –

risposta

5

Qui è una correzione temporanea fino a quando si guardano in esso nella lib supporto (ho anche messo in Sintesi https://gist.github.com/harrane/815e8a94d7ca75d964714228af69c60c)

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); 
    } 
} 
+1

Questo non viene visualizzato correttamente per me. Stai fornendo i tuoi drawable o lasciandoli gestire dal sistema? Un esempio del tuo uso di questa classe nel tuo file di layout sarebbe utile. Inoltre, c'è un modo semplice per controllare la dimensione dei drawable stellari se si lascia che il sistema li usi? –

+0

https://code.google.com/p/android/issues/detail?id=82062 – slott

Problemi correlati