Android - 将ProgressBar设置为垂直条而不是水平条?

问题描述 投票:28回答:13

我正在尝试使用ProgressBar作为计量显示器。我认为这将是一个简单的任务,并认为ProgressBar有一个属性设置为垂直,但我没有看到任何东西。

此外,我希望能够在栏的侧面显示标尺,如清楚地指示当前水平。

指针赞赏 - 谢谢!

android
13个回答
-2
投票

默认情况下不支持垂直进度条。


0
投票

简单的progrebar图像视图

viewHolder.proBarTrueImage.setMaximalValue(147);
viewHolder.proBarTrueImage.setLevel(45);
viewHolder.proBarTrueImage.setColorResource(R.color.corner_blue);

简单的课程

public class ProgressImageView extends ImageView {

private Context mContext;
private Paint paint;
private RectF rectf;

private int maximalValue = 1;
private int level = 0;
private int width;
private int height;

public ProgressImageView(Context context) {
    super(context);
    init(context, null, 0);
}

public ProgressImageView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs, 0);
}

public ProgressImageView(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs, defStyleAttr);
}

private  void init(Context context, AttributeSet attrs, int defStyleAttr){

    mContext = context;
    paint = new Paint();
    rectf = new RectF();
    paint.setColor(Color.GRAY);
    paint.setStyle(Paint.Style.FILL);
};

@Override
protected void onDraw(Canvas canvas) {

    float dif = (float) height / (float) maximalValue;
    int newHeight = height - (int) (dif * level);

    rectf.set(0,newHeight, width, height);
    canvas.drawRect(rectf, paint);

    super.onDraw(canvas);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    this.width = w;
    this.height = h;
}

public void setMaximalValue(int maximalValue) {
    this.maximalValue = maximalValue;
    invalidate();
}

public void setLevel(int level) {
    this.level = level;
    invalidate();
}

public void setColorResource(int color) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        color = mContext.getResources().getColor(color,mContext.getTheme());
    }else {
        color = mContext.getResources().getColor(R.color.corner_blue);
    }

    setColor(color);
}

public void setColor(int color){
    if (paint != null){
        paint.setColor(color);
        invalidate();
    }
}

}


0
投票

enter link description here

**检查此链接,我试图使用类似的东西,你也可以使用步进器满足您的要求,Github上的几个项目关于如何在ANDROID STUDIO中使用STEPPER **


0
投票

将其添加到xml代码android:rotation =“90”android:transformPivotX =“0dp”所以这就是你的Progress Bar xml的外观

<ProgressBar
    android:id="@+id/progressBar6"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:rotation="90"
    android:transformPivotX="0dp"
    tools:layout_editor_absoluteX="101dp"
    tools:layout_editor_absoluteY="187dp" />

-1
投票
<ProgressBar
        android:id="@+id/battery_pb"
        android:rotation="270"
        android:progress="100"
...
/>

使用android:rotation =“270”到100%就像从下到上或者android:rotation =“90”到100%就像从上到下


53
投票

我最近遇到了对垂直进度条的需求,但无法使用现有的Progress Bar小部件找到解决方案。我遇到的解决方案通常需要扩展当前的Progress Bar或者一个全新的类。我不相信推出一个新课程来实现简单的方向改变是必要的。

本文介绍了一个简单,优雅,最重要的是,实现垂直进度条的无懈可击的解决方案。我将跳过解释并简单地提供一个千篇一律的解决方案。如果您需要更多详细信息,请随时与我联系或在下面发表评论。

在drawable文件夹中创建一个xml(不是drawable-hdpi或drawable-mdpi - 将它放在drawable中)。在本例中,我调用了我的xml vertical_progress_bar.xml

这是放在xml文件中的内容:

<?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:startColor="#ff9d9e9d"
        android:centerColor="#ff5a5d5a"
        android:centerY="0.75"
        android:endColor="#ff747674"
        android:angle="180"
      />
    </shape>
  </item>
  <item android:id="@android:id/secondaryProgress">
    <clip android:clipOrientation="vertical" android:gravity="bottom">
      <shape>
        <corners android:radius="5dip" />
        <gradient
          android:startColor="#80ffd300"
          android:centerColor="#80ffb600"
          android:centerY="0.75"
          android:endColor="#a0ffcb00"
          android:angle="180"
        />
      </shape>
    </clip>
  </item>
  <item android:id="@android:id/progress">
    <clip android:clipOrientation="vertical" android:gravity="bottom">
      <shape>
        <corners android:radius="5dip" />
        <gradient
          android:startColor="#ffffd300"
          android:centerColor="#ffffb600"
          android:centerY="0.75"
          android:endColor="#ffffcb00"
          android:angle="180"
        />
      </shape>
    </clip>
</item>
</layer-list>

创建一个名为styles.xml的xml文件,并将其放在res / values中。如果您的项目已在res / values中包含styles.xml,则跳过此步骤。

修改styles.xml文件并将以下代码附加到文件末尾:

<style name="Widget">
</style>
<style name="Widget.ProgressBar">
  <item name="android:indeterminateOnly">true</item>
  <item name="android:indeterminateBehavior">repeat</item>
  <item name="android:indeterminateDuration">3500</item>
  <item name="android:minWidth">48dip</item>
  <item name="android:maxWidth">48dip</item>
  <item name="android:minHeight">48dip</item>
  <item name="android:maxHeight">48dip</item>
</style>
<style name="Widget.ProgressBar.Vertical">
  <item name="android:indeterminateOnly">false</item>
  <item name="android:progressDrawable">@drawable/progress_bar_vertical</item>
  <item name="android:indeterminateDrawable">@android:drawable/progress_indeterminate_horizontal</item>
  <item name="android:minWidth">1dip</item>
  <item name="android:maxWidth">12dip</item>
</style>

将新的垂直进度条添加到布局中。这是一个例子:

<ProgressBar
  android:id="@+id/vertical_progressbar"
  android:layout_width="12dip"
  android:layout_height="300dip"
  style="@style/Widget.ProgressBar.Vertical"
/>

这应该是您在项目中使用垂直进度条所需要做的全部工作。 (可选)您可能具有用于进度条的自定义可绘制九补丁图像。您应该在progress_bar_vertical.xml文件中进行适当的更改。我希望这可以帮助你完成你的项目!


29
投票

您必须创建自己的自定义进度条。

在你的xml中添加这个布局:

 <com.example.component.VerticalProgressBar 
        style="?android:attr/progressBarStyleHorizontal"
        android:id="@+id/verticalRatingBar1"
        android:layout_width="wrap_content"
        android:progress="50"
        android:layout_height="fill_parent" />

vertical progress bar.Java

public class VerticalProgressBar extends ProgressBar{
    private int x, y, z, w;

    @Override
    protected void drawableStateChanged() {
        // TODO Auto-generated method stub
        super.drawableStateChanged();
    }

    public VerticalProgressBar(Context context) {
        super(context);
    }

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

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

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw);
        this.x = w;
        this.y = h;
        this.z = oldw;
        this.w = oldh;
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec,
            int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);
        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) {
            return false;
        }

        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:

            setSelected(true);
            setPressed(true);
            break;
        case MotionEvent.ACTION_MOVE:
            setProgress(getMax()
                    - (int) (getMax() * event.getY() / getHeight()));
            onSizeChanged(getWidth(), getHeight(), 0, 0);

            break;
        case MotionEvent.ACTION_UP:
            setSelected(false);
            setPressed(false);
            break;

        case MotionEvent.ACTION_CANCEL:
            break;
        }
        return true;
    }

    @Override
    public synchronized void setProgress(int progress) {

        if (progress >= 0)
            super.setProgress(progress);

        else
            super.setProgress(0);
        onSizeChanged(x, y, z, w);

    }
}

或者:Jagsaund解决方案也很完美。


16
投票

我知道这是一个老帖子,但我发现这个问题的一个非常简单的解决方案,可能可以帮助某人。首先创建一个progress_drawable_vertical.xml,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <color android:color="#777" />
</item>
<item android:id="@android:id/progress">
    <clip
        android:clipOrientation="vertical"
        android:gravity="bottom">
        <shape>
            <gradient
                android:startColor="#00FF00"
                android:centerColor="#FFFF00"
                android:endColor="#FF0000"
                android:angle="90" />
        </shape>
    </clip>
</item>
</layer-list>

然后在progressBar中使用它:

<ProgressBar
    android:id="@+id/progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_centerInParent="true"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:max="100"
    android:progress="33"
    android:progressDrawable="@drawable/progress_drawable_vertical" />

我还创建了一个progress_drawable_horizo​​ntal.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <color android:color="#777" />
</item>
<item android:id="@android:id/progress">
    <clip
        android:clipOrientation="horizontal"
        android:gravity="left">
        <shape>
            <gradient
                android:startColor="#00FF00"
                android:centerColor="#FFFF00"
                android:endColor="#FF0000" />
        </shape>
    </clip>
</item>
</layer-list>

目的是维护drawable_vertical.xml中定义的相同样式

这里的关键是正确使用android:clipOrientationandroid:gravity

我发现这个解决方案here和解决方案的核心类似于jagsaund但更简单一点。


4
投票

我找到了可能最好(最简单,最通用)的解决方案:)

这是一篇很老的帖子,但是我很难找到这么简单的解决方案,所以我想我应该发布它。

只需使用scale-drawable(如果需要,可以使用9补丁),不需要任何其他代码。

例:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">  

    <item android:id="@android:id/background" android:drawable="@color/transparent"/>  

    <item android:id="@android:id/progress">
        <scale android:scaleGravity="bottom" android:scaleWidth="0%" android:scaleHeight="100%">
            <shape >
                <solid android:color="@color/blue"/>
                <corners android:topRightRadius="1dp" android:topLeftRadius="1dp"/>
            </shape>
        </scale>
    </item>
</layer-list>  

当然还有正常的代码:

<ProgressBar
    android:id="@+id/progress_bar"
    style="@android:style/Widget.ProgressBar.Horizontal"
    android:layout_width="24dp"
    android:layout_height="match_parent"
    android:max="1000"
    android:progress="200"
    android:progressDrawable="@drawable/progress_scale_drawable" />  

注意scale-drawable的xml线(魔术线):

android:scaleGravity="bottom"  //scale from 0 in y axis (default scales from center Y)  
android:scaleWidth="0%"        //don't scale width (according to 'progress')
android:scaleHeight="100%"     //do scale the height of the drawable

2
投票
This perfectly works

<?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>
            <gradient
                android:startColor="#DDDDDD"
                android:centerColor="#DDDDDD"
                android:centerY="0.75"
                android:endColor="#DDDDDD"
                android:angle="270"
                />
        </shape>
    </item>

    <item
        android:id="@android:id/progress">
        <clip
            android:clipOrientation="vertical"
            android:gravity="top">
            <shape>
                <gradient
                    android:angle="0"
                    android:startColor="#302367"
                    android:centerColor="#7A5667"
                    android:endColor="#C86D67"/>
            </shape>
        </clip>
    </item>
</layer-list>

    <ProgressBar
            android:id="@+id/progress_bar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="5dp"
            android:layout_height="match_parent"`enter code here`
            android:progressDrawable="@drawable/progress_dialog"/>

1
投票

要使用ProgressBar并使其垂直,您必须创建自己的自定义View,扩展ProgressBar视图并覆盖onDraw()方法。这将允许您以反方向绘制它。看看source codeProgressBar.onDraw()(位于链接的底部),以获取有关如何执行此操作的帮助。最好的情况是,您只需要交换一些x和y变量。


1
投票

创建进度条(我将我的代码从c#转换为java,因此可能不是100%正确)

ProgressBar progBar = new ProgressBar(Context, null, Android.resource.attribute.progressDrawable);
progBar.progressDrawable = ContextCompat.getDrawable(Context, resource.drawable.vertical_progress_bar);
progBar.indeterminate = false;

vertical_progress_bar.xml

<?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>
          <solid android:color="@color/grey" />

          <corners android:radius="20dip" />
        </shape>
      </item>
      <item android:id="@android:id/progress">
        <scale
            android:drawable="@drawable/vertical_progress_bar_blue_progress"
            android:scaleHeight="100%"
            android:scaleGravity="bottom"/>
      </item>
    </layer-list>

vertical_progress_bar_blue_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

  <corners
      android:radius="20dip" />

  <solid android:color="@color/ProgressBarFourth" />

</shape>

什么使你的酒吧垂直是scaleHeight中的scaleGravityvertical_progress_bar.xml属性。

它最终看起来像这样:

enter image description here


0
投票

我有确切的问题。创建自定义类(扩展ProgressBar)将创建难以维护的代码。使用自定义样式将导致与新操作系统(例如棒棒糖)不同主题的兼容性问题

最后,我只是将旋转动画应用于水平进度条。受到Pete的启发。

  1. 在布局xml中创建标记,就像普通的水平进度条一样。
  2. 确保ProgressBar的大小和位置在旋转后是您想要的。 (也许设置负边际会有所帮助)。在我的代码中,我从0,0旋转视图。
  3. 使用以下方法旋转并设置新进度。

码:

private void setProgress(final ProgressBar progressBar, int progress) {
    progressBar.setWillNotDraw(true);
    progressBar.setProgress(progress);
    progressBar.setWillNotDraw(false);
    progressBar.invalidate();
}

private void rotateView(final View v, float degree) {
    Animation an = new RotateAnimation(0.0f, degree);
    an.setDuration(0);
    an.setRepeatCount(0);
    an.setFillAfter(true);               // keep rotation after animation
    v.setAnimation(an);
}
© www.soinside.com 2019 - 2024. All rights reserved.