Android - 部分颜色的填充路径

San*_*San 6 android bitmap android-canvas

我试图在Android中使用Path绘制一个心形的画布.代码如下:

 @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);


        // Fill the canvas with background color
        canvas.drawColor(Color.WHITE);
       // paint.setShader(null);

        // Defining of  the heart path starts
        path.moveTo(left + WIDTH / 2, top + HEIGHT / 4); // Starting point
        // Create a cubic Bezier cubic left path
        path.cubicTo(left+WIDTH/5,top,
                left+WIDTH/4,top+4*HEIGHT/5,
                left+WIDTH/2, top+HEIGHT);
        // This is right Bezier cubic path
        path.cubicTo(left + 3 * WIDTH / 4, top + 4 * HEIGHT / 5,
                left + 4 * WIDTH / 5, top,
                left + WIDTH / 2, top + HEIGHT / 4);

         paint.setShader(new LinearGradient(0, canvas.getHeight()/4, canvas.getWidth(), canvas.getHeight()/4, new int[]{Color.RED, Color.YELLOW, Color.GREEN}, new float[]{0, 0.6f, 1}, Shader.TileMode.CLAMP));

        canvas.drawPath(path, paint);

        heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color
        heart_outline_paint.setStrokeWidth(4);
        heart_outline_paint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, heart_outline_paint);



    }
Run Code Online (Sandbox Code Playgroud)

我能够毫无问题地画出心脏,并且我能够使用FillPaint中的选项填充心脏内部的颜色.但我应该能够根据一些数据动态填充心脏,并且不能一直充满.到目前为止我所取得的成就如下:

心形状与填充颜色

我进行了广泛的搜索,并发现了很多类似的东西.其中一些包括:

  1. Android填写部分路径?
  2. 从底部到顶部逐渐填充一个圆圈

我还发现了使用Flood Fill Algorithm将画布转换为位图并在位图内填充颜色的概念,该算法允许用户填充位图内的颜色.但是,我不希望位图在触摸内心时填充颜色,而是在按钮单击操作时填充.

我认为从底部到顶部逐渐填充一个圆圈 会给我一些帮助,但它会使用一个圆圈而我并不精通Canvas,这让我很难将圆形代码调整到这样的形状.

如果有人对如何实现这一点有任何想法或任何见解,那将非常有帮助.干杯.提前致谢.

PS:我也试过setShader在Paint中使用一些技巧,但没有什么能给我我想要的东西.

编辑:

我只是偶然发现了一个想法,用一个与画布背景相同的颜色在心脏上画一个矩形,这样它看起来就像它的半满!我仍然在研究这个想法,并不确定这对我来说有多准确.如果有人有更好的想法,那么你会受到欢迎.

在此输入图像描述

San*_*San 2

我使用clipPathCanvas 中提供的功能来实现我所需要的。我用上面的方法绘制了心脏,并在其上绘制了一个矩形,然后使用该clipPath函数剪掉了心脏之外的区域。

     public static double filled_amount = .90;
     path.moveTo(left_x_moveto, left_y_moveto);
     path.cubicTo(left_x1, left_y1, left_x2, left_y2, left_x3, left_y3);
     path.cubicTo(right_x2, right_y2, right_x1, right_y1, left_x_moveto, left_y_moveto);
     path.close();
     Rect rect = new Rect((int)(canvas.getWidth()*.10),(int)(canvas.getHeight()*filled_amount),(int) canvas.getWidth(), (int) canvas.getHeight());
        canvas.clipPath(path); 
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawPath(path, paint);
        canvas.drawRect(rect, rect_paint);
        heart_outline_paint.setColor(getResources().getColor(R.color.heart_outline_color)); // Change the boundary color
        heart_outline_paint.setStrokeWidth(15);
        heart_outline_paint.setStyle(Paint.Style.STROKE);
        canvas.drawPath(path, heart_outline_paint);
Run Code Online (Sandbox Code Playgroud)

这会给我动态填充心脏的预期结果。动态改变值filled_amount并调用invalidate()会让心脏看起来像是动态被填充的。

@Henry的答案可能是一个更好的答案,但这对我来说很有效,而且我没有深入研究边缘,所以这里和那里有一点锯齿形是可以的。