2015-11-30 5 views
20

RatingBar in Android ist frustrierend.RatingBar benutzerdefinierte Vector Drawables überlagern

Ich habe https://stackoverflow.com/a/13107765 verfolgt, um eine benutzerdefinierte Bewertungsleiste mit meinen eigenen Zeichnern zu implementieren, aber alle Sterne überlagern sich einfach gegenseitig, so dass schließlich nur ein einziger Stern angezeigt wird.

Ich kann nicht für das Leben von mir herausfinden, warum.

EDIT: PNG Drawables scheinen gut zu funktionieren, SVGs als Vektor Drawables jedoch verwendet werden, dieses Problem verursacht

+0

ich war SVGs als Vektor Drawables für die leeren & gefüllt Sterne verwenden, aber dann, wenn ich PNG Drawables versucht, es funktionierte gut. Es gibt ein Problem mit der Arbeitsweise von Studio mit SVGs. –

+2

Dies ist ein Fehler, hier ist ein Problem: https://code.google.com/p/android/issues/detail?id=196713&q=vector%20ratingbar&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened –

+0

Konnten Sie @ Harranes Antwort unten erfolgreich verwenden? –

Antwort

5

Hier eine temporäre Fix, bis sie in es in der Unterstützung lib aussehen (ich es auch in Kern gesteckt haben 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

Das wird nicht richtig für mich gerendert. Stellen Sie Ihre eigenen Zeichen zur Verfügung oder lassen Sie das System damit umgehen? Ein Beispiel für die Verwendung dieser Klasse in Ihrer Layoutdatei wäre hilfreich. Gibt es außerdem eine einfache Möglichkeit, die Größe der Stern-Zeichen zu steuern, wenn Sie das System mit seinen eingebauten Stern-Zeichen verwenden? –

+0

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