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

时间:2016-04-26 10:42:51

标签: java android progress-bar android-progressbar

我正在尝试创建一个自定义水平progressBar,其中包含一定数量的圆圈指示符,如下所示: enter image description here

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

4 个答案:

答案 0 :(得分:1)

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

  1. 创建自定义视图
  2. 扩展ProgressBar,以便继承所有当前功能,而不必制作自己的setProgress方法(等。
  3. 创建自定义属性' tickInterval' (我建议将其视为%的价值而不是视图的dp,但你可以使用
  4. 如果要使用xml
  5. 中的视图,请为自定义attr创建XML文件
  6. 绘制视图时,每隔一段时间绘制指标
  7. 您可能需要在视图中调整填充,以确保您的圈子有空间。以下是您需要的简要概述:

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

    <强> attrs.xml

    <declare-styleable name="TickedProgressBarView">
        <attr name="tickInterval" format="float" />
    </declare-styleable>
    

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

答案 1 :(得分:0)

您需要为进度条创建自定义xml布局,并在Runnable中或使用AsyncTask进行计算

答案 2 :(得分:0)

最好使用custom view来实现这一目标。要设置进度,您需要定义一个如下所示的setter,这会使视图无效并调用onDraw()。

public class CustomProgressBar extends View {

    // constructors etc...

    void setProgress(int progress) {
        if (progress < 0 || progress > 100) {
            throw new IllegalArgumentException("Progress must be between 0-100!");
        }

        this.progress = progress.
        invalidate(); // tell view to redraw itself
    }
}

下一步是绘制视图中表示进度的部分,以及表示剩余工作的部分。

final Paint progressPaint = new Paint();
progressPaint.setColor(Color.RED); // could draw a bitmap or whatever, this is a simple example

@Override protected void onDraw(Canvas canvas) {
    canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); // clear previous contents
    float progressW = getWidth() * (progress / 100);
    float remainingW = getWidth() - progressPortion;

    canvas.drawRect(0, 0, progressW, getHeight(), progressPaint);
    canvas.drawRect(progressW, 0, remainingW, getHeight(), remainingPaint);

}

最后,您可以计算圆圈指示符的位置,在onDraw()中将它们绘制到画布上。

final float radius = 5;
final float circleCount = 6;

float unit = getWidth() / circleCount;
float offset = 0;

for (int i=0; i<6; i++) {
    canvas.drawCircle(offset + (radius / 2), getHeight() / 2, radius, circlePaint);
}

如果您需要有条件地显示指标,您只需在onDraw()方法中添加一个检查,以查看进度是否超过某个阈值。

答案 3 :(得分:0)

试试这个 -

带有进度条的xml -

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  android:id="@+id/progress_frame" xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:paddingEnd="16dp"
  android:layout_marginTop="10dp"
  android:paddingLeft="16dp"
  android:paddingRight="16dp"
  android:paddingStart="16dp">
  <ProgressBar
    android:id="@+id/flight_progress"
    style="@style/flght.progress.style"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:layout_marginBottom="10dp"
    android:layout_marginTop="10dp"
    android:max="100"
    android:visibility="visible"/>
  <LinearLayout android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:orientation="horizontal">
    <LinearLayout android:layout_width="0dp"
                  android:layout_weight="1"
                  android:layout_height="wrap_content">
      <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="right|end"
                 android:src="@drawable/blue_circle"/>
    </LinearLayout>
    <LinearLayout android:layout_width="0dp"
                  android:layout_weight="1"
                  android:layout_height="wrap_content">
      <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="right|end"
                 android:src="@drawable/blue_circle"/>
    </LinearLayout>

    <LinearLayout android:layout_width="0dp"
                  android:layout_weight="1"
                  android:layout_height="wrap_content">
      <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="right|end"
                 android:src="@drawable/blue_circle"/>
    </LinearLayout>
    <LinearLayout android:layout_width="0dp"
                  android:layout_weight="1"
                  android:layout_height="wrap_content">
      <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="right|end"
                 android:src="@drawable/blue_circle"/>
    </LinearLayout>

    <LinearLayout android:layout_width="0dp"
                  android:layout_weight="1"
                  android:layout_height="wrap_content">
      <ImageView android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_gravity="right|end"
                 android:src="@drawable/blue_circle"/>
    </LinearLayout>
    <ImageView android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:layout_gravity="right|end"
               android:src="@drawable/blue_circle"/>

  </LinearLayout>
</RelativeLayout>

将此添加到 styles.xml -

<style name="flght.progress.style" parent="android:Widget.ProgressBar.Horizontal">
    <item name="android:indeterminateOnly">false</item>
    <item name="android:progressDrawable">@drawable/flight_cylinder_progress_bar</item>
    <item name="android:minHeight">8dip</item>
    <item name="android:maxHeight">24dip</item>
    <item name="android:minWidth">20dip</item>
    <item name="android:maxWidth">80dip</item>
  </style>

接下来在 drawable 文件夹中添加 flight_cylinder_progress_bar -

<?xml version="1.0" encoding="UTF-8"?>
<layer-list
  xmlns:android="http://schemas.android.com/apk/res/android">
  <item
    android:id="@android:id/background">
    <shape>
      <corners
        android:radius="5dip"/>
      <gradient
        android:angle="270"
        android:centerColor="#ffdddddd"
        android:centerY="0.50"
        android:endColor="#ffdddddd"
        android:startColor="#ffdddddd"/>
    </shape>
  </item>
  <item
    android:id="@android:id/secondaryProgress">
    <clip>
      <shape>
        <corners
          android:radius="5dip"/>
        <gradient
          android:angle="90"
          android:endColor="@color/orange_dark"
          android:startColor="@color/my_orange"/>
      </shape>
    </clip>
  </item>
  <item
    android:id="@android:id/progress">
    <clip>
      <shape>
        <corners
          android:radius="5dip"/>
        <gradient
          android:angle="90"
          android:endColor="@color/my_orange"
          android:startColor="@color/orange_dark"/>
      </shape>
    </clip>
  </item>
</layer-list>

最后 drawable 文件夹中的 blue_circle.xml -

<?xml version="1.0" encoding="utf-8"?>
<shape
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:shape="oval">
  <solid android:color="@color/goibibo_blue"/>
  <size android:width="10dp"
        android:height="10dp"/>
</shape>

现在您可以简单地使用进度条来设置进度。 Output of the above code

以上是输出。您现在可以简单地调整颜色。