2015-11-30 17 views
20

androidのRatingBarはイライラしています。RatingBarカスタムVector Drawablesスーパーインポーズ

https://stackoverflow.com/a/13107765に従って独自の描画可能なカスタム評価バーを実装しましたが、すべての星が重なり合って最終的に1つの星が表示されます。

私の人生の間、私は理由を理解できません。

EDIT:彼らは私も要旨に入れてきました(サポートlibにそれに見てまで、PNGのドローアブルが正常に動作するように見える、しかし、ベクトルドローアブルとして使用SVGs一時修正この問題はここで

+0

私は空&満たさ星のベクタドローアブルとしてSVGsを使用していたが、私はPNGのドローアブルをしようとしたときに、それがうまく働きました。 StudioがSVGを処理する方法にはいくつかの問題があります。 –

+2

これはバグです。問題は次のとおりです。https://code.google.com/p/android/issues/detail?id=196713&q=vector%20ratingbar&colspec=ID%20Status%20Priority%20Owner%20Summary%20Stars%20Reporter%20Opened –

+0

下の@ harraneの答えをうまく使えましたか? –

答えて

5

をされる原因となっています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

これは私にとっては正しく表示されません。あなた自身のドロアブルを提供しているのですか?レイアウトファイルでこのクラスを使用した例が参考になります。さらに、スタードローブブルで構築されたシステムを使用させる場合、スタードローブブルのサイズを簡単に制御する方法はありますか? –

+0

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