水平进度条添加圆圈指示器

Dar*_*ski 5 java android android-progressbar progress-bar

我试图创建一个自定义水平progressBar,其中包含一定数量的圆圈指标,如下所示: 在此输入图像描述

谁能告诉我如何实现这种效果(添加圆圈指标)?

Nic*_*oso 2

假设您的圆圈指示器都处于设定的间隔(相距相同的距离),在我看来,以下是最合乎逻辑的解决方案

  1. 创建自定义视图
  2. 扩展ProgressBar,以便您继承所有当前功能,而不必创建自己的setProgress方法(等)
  3. 创建一个自定义属性“tickInterval”(我建议将其作为值的 % 点而不是视图的 dp,但您可以使用其中之一)
  4. 如果您想使用 xml 中的视图,请为自定义 attr 创建一个 XML 文件
  5. 绘制视图时,在每个间隔绘制指示器

您可能需要调整视图中的内边距,以确保圈子有空间。以下是您需要的简要说明:

public class TickedProgressBarView extends ProgressBar {

    private static final float DEFAULT_INTERVAL = 25f;
    private float INDICATOR_RADIUS;
    private Paint mTickPaint;
    private float mInterval; //%

    public TickedProgressBarView(Context context) {
        super(context);
        initPainters(context, null); //because draw is called a lot of times, don't want to do loads of allocations in onDraw
    }

    public TickedProgressBarView(Context context, AttributeSet attrs) {
        super(context, attrs);
         initPainters(context, attrs);
    }

    public TickedProgressBarView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initPainters(context, attrs);
    }

    private void initPainters(Context context, @Nullable AttributeSet attrs) {
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TickedProgressBarView, 0, 0);
            mInterval = a.getFloat(R.styleable.TickedProgressBarView_tickInterval, DEFAULT_INTERVAL);
        } else {
            mInterval = DEFAULT_INTERVAL;
        }
        //5 on the line below is HALF how many Dp wide you want the circles - ie a 10 Dp circle results from this
        INDICATOR_RADIUS = 5 * getResources().getDisplayMetrics().density + 0.5f;
        mTickPaint = new Paint();
        mTickPaint.setColor(ContextCompat.getColor(getContext(), R.color.my_color));
        mTickPaint.setStyle(Paint.Style.FILL);
        mTickPaint.setStrokeCap(Paint.Cap.ROUND);
    }

    public void setTickInterval(float intervalPercentage) {
        mInterval = intervalPercentage;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mInterval > 0f) {
            final float midHeight = canvas.getHeight() / 2f;
            final int end = canvas.getWidth();
            final int intervalPx = (int) ((end / 100f) * mInterval);
            int nextInterval = intervalPx;
            while (nextInterval <= end) {
                canvas.drawCircle(nextInterval, midHeight, INDICATOR_RADIUS, mTickPaint);
                nextInterval += intervalPx;
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

属性.xml

<declare-styleable name="TickedProgressBarView">
    <attr name="tickInterval" format="float" />
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)

attr 声明允许您使用 xml 中的视图

<!-- draw a circle every 10% along the bar -->
<com.my.packge.TickedProgressBarView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:tickInterval="10.0"
/>
Run Code Online (Sandbox Code Playgroud)