Круговой индикатор выполнения, как этого добиться - PullRequest
0 голосов
/ 26 января 2019

Я пытаюсь сделать круговой индикатор выполнения, где индикатор выполнения состоит из сплошного цвета и красной точки. Смотрите изображение ниже. В основном это таймер, где красная точка «съедает» белый цвет. Вот чего я пытаюсь достичь:

enter image description here

Вот код, который я использую из других вопросов StackOverflow

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromDegrees="270"
    android:toDegrees="270">
    <shape
        android:innerRadiusRatio="2.5"
        android:shape="ring"
        android:thickness="1dp"
        android:useLevel="true">

        <gradient
            android:angle="0"
            android:endColor="#FFFFFF"
            android:startColor="#FFFFFF"
            android:type="sweep"
            android:useLevel="false" />
    </shape>
</rotate>

С помощью этого кода я могу получить белое кольцо, но как я могу заставить его двигаться с красной точкой (используя XML)

Спасибо

PS: Это не дублирующий вопрос, так как я не видел вопроса, в котором обсуждается progress bar с двумя различными типами рисования.

Ответы [ 2 ]

0 голосов
/ 06 февраля 2019

вы можете создать пользовательский Progress View с помощью Extends View Class и переопределить onDraw() метод чтобы нарисовать полукруг, вы можете использовать drawArc ()

и используйте ValueAnimator для изменения угла дуги

Код:

TimerView.java 

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.support.v4.math.MathUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import java.util.concurrent.TimeUnit;

public class TimerView extends View {
private Paint ProgressPaint,indicatorPaint;
private float mProgressValue;
private ValueAnimator mTimerAnimator;
float stratAngel=270;
private int strokeWidth=10;

public TimerView(Context context) {
    super(context);
    ini();
}

public TimerView(Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
    ini();

}

public TimerView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    ini();

}

void ini(){
    ProgressPaint =new Paint();
    ProgressPaint.setAntiAlias(true);
    ProgressPaint.setStyle(Paint.Style.STROKE);
    ProgressPaint.setStrokeWidth(strokeWidth);
    ProgressPaint.setColor(Color.WHITE);

    indicatorPaint=new Paint();
    indicatorPaint.setAntiAlias(true);
    indicatorPaint.setStyle(Paint.Style.FILL);
    indicatorPaint.setColor(Color.RED);



}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    float w = (getWidth() - getPaddingLeft() - getPaddingRight())/2;
    float h = (getHeight() - getPaddingTop() - getPaddingBottom())/2;
    float radius = Math.min(w, h) / 2.0f;

    PointF center = new PointF(getLeft() + radius, getTop() + radius);

   RectF rect = new RectF(center.x - radius, center.y - radius,
           center.x + radius, center.y + radius);
    float progressAngel=360 * mProgressValue;
    canvas.drawArc(rect, stratAngel, progressAngel, false, ProgressPaint);
    float xPos = radius * (float)Math.cos(Math.toRadians(stratAngel+progressAngel)) + center.x;
    float yPos = radius * (float)Math.sin(Math.toRadians(stratAngel+progressAngel)) + center.y;
    canvas.drawCircle(xPos, yPos, 30, indicatorPaint);


}


public void start(int secs) {
    stop();

    mTimerAnimator = ValueAnimator.ofFloat(1f, 0f);
    mTimerAnimator.setDuration(TimeUnit.SECONDS.toMillis(secs));
    mTimerAnimator.setInterpolator(new LinearInterpolator());
    mTimerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            mProgressValue=(float) animation.getAnimatedValue();
            invalidate();
        }
    });
    mTimerAnimator.setRepeatCount(Integer.MAX_VALUE);
    mTimerAnimator.start();
}

public void stop() {
    if (mTimerAnimator != null && mTimerAnimator.isRunning()) {
        mTimerAnimator.cancel();
        mTimerAnimator = null;
        mProgressValue=0.0f;

    }
}


@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    start(5);
}




 }

и используйте его в XML-макете так:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="#dedede"
android:padding="16dp"
>
<<your package name>.TimerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
 </LinearLayout>

окончательный результат: скриншот

надеюсь, что это поможет

0 голосов
/ 06 февраля 2019

Вы должны использовать индикатор выполнения.Добавьте к вашему коду индикатор выполнения, затем добавьте фоновый XML-файл, как показано ниже:

 <?xml version="1.0" encoding="UTF-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android"
        android:fromDegrees="120"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="140">
        <item android:id="@android:id/background">
            <shape
                android:innerRadiusRatio="2.6"
                android:shape="ring"
                android:useLevel="false"
                android:angle="0"
                android:type="sweep"
                android:thicknessRatio="80.0">
                <solid android:color="#d3d3d3"/>
            </shape>
        </item>
        <item android:id="@+id/rate_progress">
            <rotate
                android:fromDegrees="270"
                android:toDegrees="270">
                <shape
                    android:innerRadiusRatio="2.78"
                    android:shape="ring"
                    android:angle="0"
                    android:type="sweep"
                    android:thicknessRatio="15.0">
                    <solid android:color="@color/colorAccent"/>
                </shape>
            </rotate>
        </item>
    </layer-list>

установите под фоном свой индикатор выполнения.код ниже - мой пример:

LayerDrawable layerDrawable = (LayerDrawable) progressBar.getContext().getResources()
            .getDrawable(R.drawable.rate_background);
    RotateDrawable progressDrawable = (RotateDrawable) layerDrawable
            .findDrawableByLayerId(R.id.rate_progress);
    GradientDrawable gradientDrawable = (GradientDrawable) progressDrawable.getDrawable();
    if (gradientDrawable != null) {
        gradientDrawable.setColor(Color.parseColor(color));
        progressBar.setProgressDrawable(layerDrawable);
    }
    progressBar.setProgress(rate);

И добавьте стиль ниже к вашему индикатору прогресса

 style="?android:attr/progressBarStyleHorizontal"
...