Android画布(Canvas)之- 圆环,利用Path切除一个扇形,形成一段圆弧效果

移动开发 码拜 4年前 (2016-09-22) 1147次浏览
话不多说,情况是这样:ApiDemo大家都熟吧,其中Sweep这个demo大家一定也都看过,即利用SweepGradient这个Shader使圆随着弧度的变换有个渐进色的效果。
现在本人有个想法,即想实现相似于下图中的效果
Android画布(Canvas)之- 圆环,利用Path切除一个扇形,形成一段圆弧效果
描述一下本人的效果吧:
1. 缺口的圆环;
2. 圆环颜色渐进(颜色配比在下面代码中还未给出,不影响代码分析);
3. 圆环的刻度(即虚线)稳定;
首先需要强调的是,大家的答案里面千万别给canvas.drawArc()这个答案,这个答案不符合本人的需求,原因是不同的弧度画出的圆环,其刻度是会随意移动的;
再说说本人的思路:即在从圆环的圆心利用画布类的canvas方法ClipPath方法截取本人想要去掉的这段弧度所在的画布
然后再在剩余的画布上画圆形,那么自然截取的图为本人上图中想要达到的效果了。
值得大家注意的是:下面这段代码中,当不给画笔设置SweepGradient属性时,是能够达到圆弧效果,但是这样的话,颜色又不符合上述要求了。

public class MainActivity extends Activity {
    private ImageView mScanImage;
    private ImageView mSecondImage;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }
    private static class SampleView extends View {
        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        private float mRotate;
        private Matrix mMatrix = new Matrix();
        private Shader mShader;
        private boolean mDoTiming;
        public SampleView(Context context) {
            super(context);
            setFocusable(true);
            setFocusableInTouchMode(true);
            float x = 160;
            float y = 100;
            mShader = new SweepGradient(x, y, new int[] { Color.GREEN,
                                                  Color.RED,
                                                  Color.BLUE,
                                                  Color.GREEN }, null);
            mPaint.setShader(mShader);
            mPaint.setStyle(Style.STROKE);
            PathEffect effect = new DashPathEffect(new float[] { 5, 8, 5, 8}, 1);
            mPaint.setPathEffect(effect);
            mPaint.setStrokeWidth(10);[/color]
        }
        @Override protected void onDraw(Canvas canvas) {
            Paint paint = mPaint;
            float x = 160;
            float y = 100;
            canvas.drawColor(Color.WHITE);
            mMatrix.setRotate(mRotate, x, y);
            mShader.setLocalMatrix(mMatrix);
            mRotate += 3;
            if (mRotate >= 360) {
                mRotate = 0;
            }
            invalidate();
            if (mDoTiming) {
                long now = System.currentTimeMillis();
                for (int i = 0; i < 20; i++) {
                    canvas.drawCircle(x, y, 80, paint);
                }
                now = System.currentTimeMillis() - now;
                android.util.Log.d("skia", "sweep ms = " + (now/20.));
            }
            else {
                RectF rect = new RectF(x - 80, y - 80, x + 80, y + 80);
                Paint paintRect = new Paint();
                paintRect.setColor(Color.RED);
                paintRect.setStyle(Style.STROKE);
                canvas.drawRect(rect, paintRect);
                Path path = new Path();
                path.addArc(rect, 60, 60);
                canvas.clipPath(path);
                //canvas.clipPath(path,Op.XOR);
                canvas.drawCircle(x, y, 80, paint);
            }
        }
    }
}

这是本人的代码,感觉思路是没错的,原因是单独画带刻度圆弧或单画带颜色渐进的圆都是能实现的。可是加上渐进效果,同时clipPath的时候出现了问题;
代码中31-34行以及61-69行为本人本人在apidemo中sweep这个例子上新增的代码,可是最后实现的效果却是下面这样:
Android画布(Canvas)之- 圆环,利用Path切除一个扇形,形成一段圆弧效果
或这样:
Android画布(Canvas)之- 圆环,利用Path切除一个扇形,形成一段圆弧效果
急求各路高手大仙帮忙解答;或有更好的方案也望不吝赐教…
高分相送!

解决方案

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明Android画布(Canvas)之- 圆环,利用Path切除一个扇形,形成一段圆弧效果
喜欢 (1)
[1034331897@qq.com]
分享 (0)