Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/224.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SweepGradient Android-如何设置渐变的开始角度_Android_Android Canvas_Gradient_Ondraw - Fatal编程技术网

SweepGradient Android-如何设置渐变的开始角度

SweepGradient Android-如何设置渐变的开始角度,android,android-canvas,gradient,ondraw,Android,Android Canvas,Gradient,Ondraw,我很难理解如何使用扫描渐变在画布上从特定角度显示渐变颜色 例如:如果我有一个从下午1点到3点的弧,我想提供一个渐变作为颜色。渐变应该从下午2点开始 我有下面的代码,它显示了颜色,没有应用任何渐变 SweepGradient sweepGradient = new SweepGradient(provideRectF().width() / 2, provideRectF().height() / 2,

我很难理解如何使用
扫描渐变
画布上从特定角度显示渐变颜色

例如:如果我有一个从下午1点到3点的弧,我想提供一个
渐变
作为
颜色
渐变应该从下午2点开始

我有下面的代码,它显示了
颜色
,没有应用任何渐变

 SweepGradient sweepGradient = new
                                SweepGradient(provideRectF().width() / 2, provideRectF().height() / 2,
                                arcColors, new float[]{
                                0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f, 1.0f
                        });

                        Matrix matrix = new Matrix();
                        matrix.postRotate(currentAngle, provideRectF().width() / 2, provideRectF().height() / 2);
                        sweepGradient.setLocalMatrix(matrix);

如何使我的
颜色
显示给定圆弧从下午2点开始的梯度(角度)?

此答案基于Attila Tanyi的答案

<> >为了更好地理解<代码> SurePrime,让我们先用一个<代码> > SurePrime绘制整个屏幕,该屏幕位于屏幕中部,显示与时钟表面对应的部分(请注意,下午1PM到2PM之间的区域是一个纯色,因为这是设置的一部分):

职位:

// positions for a clock face
// note: we need an opening position 0.0f as well as a closing position 1.0f, both of which belong to 3 pm
float[] positions = {0.0f,
            1/12f, 2/12f, 3/12f, 
            4/12f, 5/12f, 6/12f,
            7/12f, 8/12f, 9/12f,
            10/12f, 11/12f, 1.0f};
颜色:

int yellow = 0xFFFFFF88;
int blue = 0xFF0088FF;
int white = 0xFFFFFFFF;
int black = 0xFF000000;

// provide as many color values as there are positions
// we want to paint a "normal color" from 1pm to 2pm and then a gradient from 2pm to 3 pm
int[] colors = { black, // the first value is for 3 pm, the sweep starts here
        yellow, // 4
        white,  // 5
        black,  // 6
        white,  // 7
        yellow, // 8
        blue,   // 9
        black,  // 10
        white,  // 11
        black,  // 12
        blue,   // 1 constant color from 1pm to 2pm
        blue,   // 2
        white // the last value also is at 3 pm, the sweep ends here
};
int[] colors = {      
        primaryColor,
        primaryColor,
        accentColor };
初始化
路径
绘制

private Path circle = new Path();
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

// ...
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(30);
我尝试了一个自定义的
视图
,并在
onLayout()
中配置了渐变。因为这篇文章是关于画圆弧的,所以我下一步尝试了一个完整的圆圈:

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    // use a square rectangle which does not touch the screen borders:
    float squareMaxWidth = Math.min(right - left, bottom - top) - 20;
    RectF circleRect = new RectF(left + 20, top + 20, left + squareMaxWidth, top + squareMaxWidth);
    // draw a full circle
    circle.addArc(circleRect, 180, 360);
    // calculate its center
    float centerH = (circleRect.right + circleRect.left)*0.5f;
    float centerV = (circleRect.bottom + circleRect.top)*0.5f;

    sweepGradient = new SweepGradient(centerH,centerV, colors, positions);
    paint.setShader(sweepGradient);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawPath(circle, paint);
}
结果是:

接下来,让我们只绘制边框:更改
Paint
样式

paint.setStyle(Paint.Style.STROKE);

最后,在下午1点到3点之间画一条弧。记住,下午3点的角度为零,钟面上的一个部分对应30度。所以在
onLayout()
中我们有

circle.addArc(circleRect, 300, 60);

另一个例子:如果您想在下午4:15到4:45之间绘制一条弧线,渐变从下午4:33开始,您可以得到以下图片(在整个
扫描渐变上绘制彩色弧线,每“小时”交替黑白)

颜色:

int yellow = 0xFFFFFF88;
int blue = 0xFF0088FF;
int white = 0xFFFFFFFF;
int black = 0xFF000000;

// provide as many color values as there are positions
// we want to paint a "normal color" from 1pm to 2pm and then a gradient from 2pm to 3 pm
int[] colors = { black, // the first value is for 3 pm, the sweep starts here
        yellow, // 4
        white,  // 5
        black,  // 6
        white,  // 7
        yellow, // 8
        blue,   // 9
        black,  // 10
        white,  // 11
        black,  // 12
        blue,   // 1 constant color from 1pm to 2pm
        blue,   // 2
        white // the last value also is at 3 pm, the sweep ends here
};
int[] colors = {      
        primaryColor,
        primaryColor,
        accentColor };
要计算位置,需要做一些数学计算:

60分钟=一小时~1/12f
3分钟=1小时/20~1/240f
15分钟=5*3分钟~5/240f=1/48f
45分钟=3*15分钟~1/16f
33分钟=11*3分钟~11/240f

类似地,可以计算开始角度和扫掠角度的值:

一小时~30度
一分钟~0.5度


非常感谢您如此详细的回答!位置阵列的用途是什么?这似乎最让我困惑。@User251182-让我困惑的是角度是以度(0到360)为单位测量的,但对于位置,人们会看到完整的圆弧(从下午3点顺时针到下午3点),并将其视为“一条完整的路径”(也称为100%或1.0f)。各个位置类似于百分比值:0.1f表示路径长度的10%。你需要一个钟面,所以我用分母为12的分数,明白了。因此,我说的颜色数组表示从0度(即下午3点)开始的每个位置是否正确?@user251182-是的,每个位置需要一种颜色。扫描渐变类似于两个对象之间的一系列过渡colors@user2511882-由于您只对下午1点到3点之间的arc感兴趣,因此您可以忽略大部分位置。这也应该起作用:int[]colors={white,yellow,blue,blue,white};浮动[]位置={0.0f,1/12f,9/12f,10/12f,11/12f,1.0f};