dynamic绘制自定义的圈子细分

我的客户希望在应用程序中使用以下小部件:
在这里输入图像说明
Text来自服务器。 渐变angular度取决于也来自服务器的variables。 此外,客户希望梯度被dynamic填充(用户必须看到如何从0开始填充梯度)。
现在我做了以下工作:我使用两个图像 – 一个是彩色圆圈,第二个是灰色圆圈。 我创build了一个具有一定angular度的圆弧段,并将其作为一个蒙板应用于灰色圆圈,然后将彩色圆圈与新的灰色圆圈(其中一个扇段被切断)相结合。
这是我的代码。 我初始化调用initializeVarsForCompoundImDrawing的variables,然后在第二次调用makeCompoundImage ,最后调用nullVarsForCompoundImDrawing释放资源:

 private static Bitmap notColoredBitmap; private static Bitmap coloredBitmap; private static Bitmap notColoredWithMaskBitmap; private static Bitmap finalBitmap; private static Canvas notColoredWithMaskCanvas; private static Paint paintForMask; private static Paint smoothPaint; private static Canvas finalCanvas; private static RectF rectForMask; public static void initializeVarsForCompoundImDrawing() { Context context = MainApplication.getContext(); notColoredBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.not_colored); coloredBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.colored); paintForMask = new Paint(Paint.ANTI_ALIAS_FLAG); paintForMask.setStyle(Paint.Style.FILL); paintForMask.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); rectForMask = new RectF(0, 0, notColoredBitmap.getWidth(), notColoredBitmap.getHeight()); smoothPaint = new Paint(Paint.ANTI_ALIAS_FLAG); } public static void nullVarsForCompoundImDrawing() { notColoredBitmap = null; coloredBitmap = null; paintForMask = null; rectForMask = null; smoothPaint = null; } public static void makeCompoundImage(ImageView imageView, int angle) { notColoredWithMaskBitmap = Bitmap.createBitmap(notColoredBitmap.getWidth(), notColoredBitmap.getHeight(), Bitmap.Config.ARGB_8888); notColoredWithMaskCanvas = new Canvas(notColoredWithMaskBitmap); notColoredWithMaskCanvas.drawBitmap(notColoredBitmap, 0, 0, smoothPaint); notColoredWithMaskCanvas.drawArc(rectForMask, 270, angle, true, paintForMask); finalBitmap = Bitmap.createBitmap(notColoredBitmap.getWidth(), notColoredBitmap.getHeight(), Bitmap.Config.ARGB_8888); finalCanvas = new Canvas(finalBitmap); finalCanvas.drawBitmap(coloredBitmap, 0, 0, smoothPaint); finalCanvas.drawBitmap(notColoredWithMaskBitmap, 0, 0, smoothPaint); imageView.setImageBitmap(finalBitmap); } 

第一个问题:是否有可能改善这个代码使用更less的资源?
第二个问题:如何将文本添加到finalBitmap (现在它是一个TextView ,它显示在ImageView的顶部与图像)?

你可以使用我的项目为例https://github.com/donvigo/CustomProgressControls 。 它还没有在github上logging,但我希望你能理解我的代码:)

编辑:文本圈内它不是一个TextView ,它使用paint

回答你的问题:是的,它可以做的更容易,更容易:

 public class Ring extends View { private Bitmap mBack; private Paint mPaint; private RectF mOval; private Paint mTextPaint; public Ring(Context context) { super(context); Resources res = getResources(); mBack = BitmapFactory.decodeResource(res, R.drawable.back); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); Bitmap ring = BitmapFactory.decodeResource(res, R.drawable.ring); mPaint.setShader(new BitmapShader(ring, TileMode.CLAMP, TileMode.CLAMP)); mOval = new RectF(0, 0, mBack.getWidth(), mBack.getHeight()); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setTextSize(24); mTextPaint.setTextAlign(Align.CENTER); } @Override protected void onDraw(Canvas canvas) { canvas.translate((getWidth() - mBack.getWidth()) / 2, (getHeight() - mBack.getHeight()) / 2); canvas.drawBitmap(mBack, 0, 0, null); float angle = 220; canvas.drawArc(mOval, -90, angle, true, mPaint); canvas.drawText("Text", mBack.getWidth() / 2, (mBack.getHeight() - mTextPaint.ascent()) / 2, mTextPaint); } } 

编辑:

这是一个替代解决scheme(没有集中,没有文字,只是一个概念)

 class Ring extends View { private Bitmap back; private Bitmap ring; private RectF oval; private Paint arcPaint; public Ring(Context context) { super(context); Resources res = getResources(); back = BitmapFactory.decodeResource(res, R.drawable.back); ring = BitmapFactory.decodeResource(res, R.drawable.ring); arcPaint = new Paint(); arcPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR)); oval = new RectF(-1, -1, ring.getWidth()+1, ring.getHeight()+1); } @Override protected void onDraw(Canvas canvas) { canvas.drawARGB(0xaa, 0, 255, 0); canvas.drawBitmap(back, 0, 0, null); canvas.saveLayer(oval, null, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG); canvas.drawBitmap(ring, 0, 0, null); float angle = 300; canvas.drawArc(oval, angle-90, 360-angle, true, arcPaint); canvas.restore(); } } 

我一直在做类似的事情 – animation进度栏,就像你的照片一样,但进度条的每一个状态都在改变。 里面我有时间的文字,一直到进度到期。 我只是把这个看法放在这里,也许对某个人有用。

 public class TickerView extends View { private Paint mPaint, backPaint; private RectF mOval; private Paint mTextPaint; private int time; private float progress = 100; public TickerView(Context context) { super(context); init(); } public TickerView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TickerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init(){ mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.WHITE); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(UIHelper.getPixel(1));//1dp mPaint.setDither(true); // set the dither to true mPaint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want mPaint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too mPaint.setPathEffect(new PathEffect()); // set the path effect when they join. backPaint = new Paint(Paint.ANTI_ALIAS_FLAG); backPaint.setColor(ColorManager.roseLine); backPaint.setStyle(Paint.Style.STROKE); backPaint.setStrokeWidth(UIHelper.getPixel(1));//1dp backPaint.setDither(true); // set the dither to true backPaint.setStrokeJoin(Paint.Join.ROUND); // set the join to round you want backPaint.setStrokeCap(Paint.Cap.ROUND); // set the paint cap to round too backPaint.setPathEffect(new PathEffect()); // set the path effect when they join. measure(MeasureSpec.EXACTLY, View.MeasureSpec.EXACTLY); mOval = new RectF(0, 0, getMeasuredWidth(), getMeasuredHeight()); mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mTextPaint.setColor(Color.WHITE); mTextPaint.setTypeface(FontSetter.HelveticaNeueLight); mTextPaint.setTextSize(UIHelper.getPixel(15)); mTextPaint.setTextAlign(Paint.Align.CENTER); mOval = new RectF(UIHelper.getPixel(1), UIHelper.getPixel(1), getWidth(), getHeight()); } /** * * @param persent in range [0..1] * @param time - seconds left before progress will be executed */ public void setProgress(float persent, int time){ this.progress = persent; this.time = time; invalidate(); } @Override protected void onDraw(Canvas canvas) { canvas.drawText("" + time, getWidth() / 2, (getHeight() - mTextPaint.ascent()) / 2, mTextPaint); mOval.right = getWidth() - UIHelper.getPixel(1); mOval.bottom = getHeight() - UIHelper.getPixel(1); canvas.drawArc(mOval, 0, 360, false, backPaint); int angle = (int)( progress * 360 ); canvas.drawArc(mOval, -90, angle, false, mPaint); } 

}