我正在尝试将 ProgressBar 作为类似计量的显示。我原以为这是一项容易的任务,并认为 ProgressBar 有一个可以设置为垂直的属性,但我没有看到任何东西。
此外,我希望能够在条形图的侧面显示标尺样式的指示器,以清晰地指示当前水平。
欢迎提供指引 - 谢谢!
我正在尝试将 ProgressBar 作为类似计量的显示。我原以为这是一项容易的任务,并认为 ProgressBar 有一个可以设置为垂直的属性,但我没有看到任何东西。
此外,我希望能够在条形图的侧面显示标尺样式的指示器,以清晰地指示当前水平。
欢迎提供指引 - 谢谢!
我最近需要使用垂直进度条,但无法通过现有的进度条小部件找到解决方案。我找到的解决方案通常要求扩展当前的进度条或完全创建一个新类。我不认为必须要推出一个新类来实现简单的方向更改。
本文介绍了一种简单、优雅且最重要的是非黑客解决方案来达到垂直进度条。 我将跳过解释,直接提供一个万能解决方案。如果您需要更多详情,请随时与我联系或在下面评论。
在drawable文件夹中创建一个xml文件(不是drawable-hdpi或drawable-mdpi -- 放置于drawable中)。以本示例为例,我称之为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文件中进行更改。 希望这对你的项目有所帮助!
您需要创建自己的自定义进度条。
在您的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" />
VerticalProgressBar.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的解决方案也非常完美。
我知道这是一篇旧帖子,但我找到了一个非常简单的解决方案,也许可以帮助某些人。 首先创建一个名为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
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_horizontal.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>
旨在保持progress_drawable_vertical.xml文件中定义的相同风格。
关键在于正确使用android:clipOrientation
和android:gravity
属性。
scale-drawable
(或9-patch,如果您想要),不需要任何其他代码。<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
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"/>
简单易行的方法:
只需将一个视图添加到LinearLayout
中并进行缩放。
<LinearLayout
android:layout_width="4dp"
android:layout_height="300dp"
android:background="@color/md_green_50"
android:orientation="vertical">
<View
android:id="@+id/progressView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="top"
android:layout_weight="1"
android:background="@color/md_green_500"
android:scaleY="0.0" />
</LinearLayout>
将视图的pivotY
设置为零:
progressView.pivotY = 0F
现在你可以使用 scaleY
在 0F
和 1F
之间填充进度:
progressView.scaleY = 0.3F
animate()
动画进度:progressView.animate().scaleY(0.3F).start()
progressView.animate().scaleY(0.3F).start()
来调整进度,其中0.3F
是进度值。 - Amir创建进度条(我将我的代码从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>
使你的垂直进度条竖直的是 vertical_progress_bar.xml
中的 scaleHeight
和 scaleGravity
属性。
最终效果如下图所示:
android:rotation="270"
<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" />
代码:
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);
}