【问题标题】:Horizontal progressbar add circle indicators水平进度条添加圆形指示器
【发布时间】:2016-08-20 03:26:31
【问题描述】:

我正在尝试创建一个自定义的水平进度条,其中包含一定数量的圆形指示器,例如:

谁能告诉我怎样才能达到这个效果(添加圆圈指标)?

【问题讨论】:

  • 你能得到解决方案吗,如果有请分享一下。

标签: java android progress-bar android-progressbar


【解决方案1】:

假设你的圆圈指标都在一个设定的间隔(相距相同的距离),在我看来,以下似乎是最合乎逻辑的解决方案

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

}

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

【讨论】:

  • 你能帮我绘制进度条,这样我就可以得到金色填充物了吗?感谢您的精彩回答
  • 它是您需要的一个非常简单的线性渐变,将 centerColor 设置为棕色,然后将开始和结束颜色设置为具有 alpha 透明度的颜色。将其设置为可绘制的进度。我的手机写不了代码,如果你不能解决,明天开一个新问题,我会从我的电脑上看一下
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    最好使用custom view 来实现这一点。要设置进度,您可以定义如下所示的设置器,它使视图无效并调用 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() 方法中添加一个检查,以查看进度是否超过某个阈值。

    【讨论】:

      【解决方案4】:

      试试这个-

      你的带有进度条的 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>
      

      接下来将这个flight_cylinder_progress_bar添加到drawable文件夹中-

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

      现在您可以简单地使用进度条来设置进度。

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

      【讨论】:

        猜你喜欢
        • 2015-11-14
        • 2015-09-06
        • 1970-01-01
        • 2016-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        相关资源
        最近更新 更多