android 自定义圆弧,动态绘制自定义圆弧段

我的客户想在应用程序中使用以下小部件:

SQnWp.png

Text来自服务器。 渐变角度取决于也来自服务器的variables。 此外,客户希望动态填充渐变(用户必须从0开始查看渐变的填充方式)。

现在我执行以下操作:我使用两个图像 – 一个是彩色圆圈,第二个是灰色圆圈。 我创建一个具有一定角度的圆弧段,并将其作为蒙版应用于灰色圆圈,然后将彩色圆圈与新的灰色圆圈(扇形截止的位置)相结合。

这是我的代码。 我初始化调用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); }

第一个问题:是否可以改进此代码以减少资源使用?

第二个问题:如何将文本添加到finalBitmap (现在它是一个TextView ,它显示在带有图像的ImageView顶部)?

回答你的问题:是的,它可以更简单,更轻松地完成:

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

编辑:

这是一个替代解决方案(没有居中,没有文字,只是一个概念)

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(); } }

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

编辑:圆圈内的文字它不是TextView ,它是使用paint 。

我一直在做类似的事情 – 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); }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值