Подтвердить что ты не робот

Нарисовать закругленную краевую дугу в андроиде с тиснением

Я пытаюсь разработать пользовательский компонент, т.е. слайдер дуги, я делаю это с дугой и большим пальцем, но не могу понять, как я могу нарисовать закругленную дугу края, а также эффект рельефа в нем. на данный момент слайдер выглядит примерно так.

enter image description here

код для рисования дуги

private void drawSlider(Canvas canvas) {
    float sweepDegrees = (value * arcWidthInAngle)
            / (maximumValue - minimumValue);

    // the grey empty part of the circle
    drawArc(canvas, startAngle, arcWidthInAngle, mTrackColor);
    // the colored "filled" part of the circle
    drawArc(canvas, startAngle, sweepDegrees, mFillColor);

    // the thumb to drag.       
    int radius = ((diameter/2) - (mArcThickness/2));
    Point thumbPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);

    thumbPoint.x = thumbPoint.x - (mThumbDiameter/2);
    thumbPoint.y = thumbPoint.y - (mThumbDiameter/2);

    Bitmap thumbBitmap = BitmapFactory.decodeResource(
            mContext.getResources(), R.drawable.circle25);

    thumbBitmap = getResizedBitmap(thumbBitmap, mThumbDiameter, mThumbDiameter);
    canvas.drawBitmap(thumbBitmap, thumbPoint.x, thumbPoint.y,
            null);  

}

private void drawArc(Canvas canvas, float startAngle, float sweepDegrees,
        Paint paint) {
    if (sweepDegrees <= 0 || sweepDegrees > arcWidthInAngle) {
        return;
    }
    path.reset();
    path.arcTo(outerCircle, startAngle, sweepDegrees);
    path.arcTo(innerCircle, startAngle + sweepDegrees, -sweepDegrees);
    // innerCircle.
    path.close();
    canvas.drawPath(path, paint);
}

Я стремлюсь к дуге что-то вроде этого

enter image description here

4b9b3361

Ответ 1

Мне удалось построить дугу, что-то вроде ниже

enter image description here

Что я сделал, так это вычисление начальной и конечной точки дуги, и там я рисую круг с диаметром, равным толщине дуги.

Код для этого

private void drawSlider(Canvas canvas) {
    float sweepDegrees = (value * arcWidthInAngle)
            / (maximumValue - minimumValue);

    // the grey empty part of the arc       
    drawArc(canvas, startAngle, arcWidthInAngle, mTrackColor);

    // the colored "filled" part of the arc
    drawArc(canvas, startAngle, sweepDegrees, mFillColor);

    // the thumb to drag.       
    int radius = ((diameter/2) - (mArcThickness/2));
    Point thumbPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);

    thumbPoint.x = thumbPoint.x - (mThumbDiameter/2);
    thumbPoint.y = thumbPoint.y - (mThumbDiameter/2);

    Bitmap thumbBitmap = BitmapFactory.decodeResource(
            mContext.getResources(), R.drawable.circle25);

    thumbBitmap = getResizedBitmap(thumbBitmap, mThumbDiameter, mThumbDiameter);
    canvas.drawBitmap(thumbBitmap, thumbPoint.x, thumbPoint.y,
            null);

    //drawArc(canvas, startAngle, startAngle + sweepDegrees, white);
}
private void drawArc(Canvas canvas, float startAngle, float sweepDegrees,
        Paint paint) {
    if (sweepDegrees <= 0 || sweepDegrees > arcWidthInAngle) {
        return;
    }
    path.reset();


    int radius = ((diameter/2) - (mArcThickness/2));
    Point startPoint = calculatePointOnArc(centerX, centerY, radius, startAngle);
    Point endPoint = calculatePointOnArc(centerX, centerY, radius, startAngle + sweepDegrees);


    path.arcTo(outerCircle, startAngle, sweepDegrees);
    path.arcTo(innerCircle, startAngle + sweepDegrees, -sweepDegrees);
    // drawing the circle at both the end point of the arc to git it rounded look.
    path.addCircle(startPoint.x, startPoint.y, mArcThickness/2, Path.Direction.CW);
    path.addCircle(endPoint.x, endPoint.y, mArcThickness/2, Path.Direction.CW);

    path.close();            

    canvas.drawPath(path, paint);
}
    // this is to calculate the end points of the arc
private Point calculatePointOnArc(int circleCeX, int circleCeY, int circleRadius, float endAngle) 
    {
    Point point = new Point();
    double endAngleRadian = endAngle * (Math.PI / 180);

    int pointX = (int) Math.round((circleCeX + circleRadius * Math.cos(endAngleRadian)));
    int pointY = (int) Math.round((circleCeY + circleRadius * Math.sin(endAngleRadian)));

    point.x = pointX;
    point.y = pointY;

    return point;
}
// for the emboss effect set maskfilter of the paint to EmbossMaskFilter 
    private Paint mTrackColor = new Paint();
    MaskFilter  mEmboss = new EmbossMaskFilter(new float[] { 0.0f, -1.0f, 0.5f},
            0.8f, 15, 1.0f);
    mTrackColor.setMaskFilter(mEmboss);

Ответ 2

Для закругленных краев вы можете использовать метод Paint.setStrokeCap ​​(). Кроме того, колпачок по умолчанию имеет значение BUTT. Вместо этого следует использовать крышку Paint.Cap.ROUND.

Например:

Paint mFillColor = new Paint();
mFillColor.setStrokeCap(Paint.Cap.ROUND)

Ответ 3

Вы используете путь для рисования дуги. Используйте CornerPathEffect для округления углов. Пример здесь CornerPathEffect example.

И вот пример эффекта тиснения. Я не уверен, что это то, чего ты хочешь. Embossed effect example

Ответ 4

Используйте метод Paint.setStrokeCap ​​(). Вам понадобится Paint.Cap.ROUND. По умолчанию используется Paint.Cap.BUTT. Существует аналогичное свойство Path, которое называется соединением путей. Он определяет, как рисовать части пути, к которым присоединяются составляющие сегменты. Чтобы установить его, используйте Path.setPathJoin(). Возможно, вам это понадобится в будущем. Удачи.