代码之家  ›  专栏  ›  技术社区  ›  Snake

循环进度条,如何实现这一点

  •  2
  • Snake  · 技术社区  · 5 年前

    我试着做一个圆形的进度条,进度条由纯色和红点组成。见下图。基本上,它是一个计时器,其中红点“吃掉”白色。 这就是我努力实现的目标:

    enter image description here

    <?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 回复  |  直到 5 年前
        1
  •  1
  •   Amir Mohsenian    5 年前

    你应该使用进度条。将进度条视图添加到代码中,然后添加背景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"
    
        2
  •  1
  •   Amrdroid    5 年前

    您可以通过扩展创建自定义进度视图 View 类和重写 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);
    }
    
    
    
    
     }
    

    <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>
    

    screenshot