android中两边圆形的进度条
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2078809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Progress bar rounded on both sides in android
提问by youri
I am trying to create a custom progress bar in android. I have used the following xml file for it (progress_bar_horizontal.xml):
我正在尝试在 android 中创建一个自定义进度条。我为此使用了以下 xml 文件 (progress_bar_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">
<shape>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FFFF"/>
</shape>
</item>
<item android:id="@android:id/secondaryProgress">
<clip>
<shape>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FF00"/>
</shape>
</clip>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="8dip" />
<stroke android:width="2dip" android:color="#FFFF"/>
<solid android:color="#FF00"/>
</shape>
</clip>
</item>
</layer-list>
Everything works great apart from the fact I would like to have the progress in my progress bar rounded on both sides. The aforementioned code makes a progress bar to be rounded on the left hand side and simply cut (not rounded) on the right hand side. It is because of the clip tag probably. Could you please help me on that? What should i change to have the progress in my progress bar rounded on both sides?
除了我希望在我的进度条中的进度条两边都四舍五入之外,一切都很好。上述代码使进度条在左侧变圆,并在右侧简单地切割(不圆化)。可能是因为剪辑标签。你能帮我解决这个问题吗?我应该改变什么才能让我的进度条的进度在两边都四舍五入?
The full layout goes below:
完整布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/gradient_progress"
android:padding="10dip"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<TextView
android:id="@+id/progress_header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="Uploading"
/>
<TextView
android:id="@+id/progress_percent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF000000"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textStyle="bold"
android:text="55%"
android:paddingLeft="10dip"
/>
</LinearLayout>
<ProgressBar
android:id="@+id/progress_bar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:progressDrawable="@drawable/progress_bar_horizontal"
android:maxHeight="12dip"
android:minHeight="12dip"
android:max="100"
/>
</LinearLayout>
</LinearLayout>
Here is the result of my effort: link text
这是我努力的结果:链接文本
I would like the red bar to have rounded edges on the right hand side as well. Thank you so much for your comments.
我希望红色条的右侧也有圆形边缘。非常感谢您的评论。
回答by Funktional
Here's an updated answer for the times:
这是时代的更新答案:
The Android source code uses Patch 9 files to achieve the effect: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/res/res/drawable/progress_horizontal_holo_dark.xml/
Android源码使用Patch 9文件实现效果:http: //grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/frameworks/base/core/ res/res/drawable/progress_horizontal_holo_dark.xml/
So start in your layout xml:
所以从你的布局 xml 开始:
<ProgressBar
android:id="@+id/custom_progress_bar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:indeterminateOnly="false"
android:progressDrawable="@drawable/custom_progress_bar_horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:minHeight="13"
android:progress="33"
android:secondaryProgress="66" />
You can move a lot of this to a style xml but that's beside the point. What we really care about is android:progressDrawable="@drawable/custom_progress_bar_horizontal"
- which is going to allow us to specify our own custom progress bars:
您可以将其中的很多内容移动到样式 xml 中,但这不是重点。我们真正关心的是android:progressDrawable="@drawable/custom_progress_bar_horizontal"
- 这将允许我们指定我们自己的自定义进度条:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background"
android:drawable="@android:drawable/custom_progress_bg" />
<item android:id="@android:id/secondaryProgress">
<scale android:scaleWidth="100%"
android:drawable="@android:drawable/custom_progress_secondary" />
</item>
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%"
android:drawable="@android:drawable/custom_progress_primary" />
</item>
</layer-list>
Or you don't have to use a Patch 9 for your background- for example here's a simple white background with a 1dp border:
或者您不必为您的背景使用补丁 9 - 例如,这是一个带有 1dp 边框的简单白色背景:
<item android:id="@android:id/background">
<shape>
<corners android:radius="6.5dp" />
<solid android:color="@android:color/white" />
<stroke
android:width="1dp"
android:color="@android:color/darker_gray" />
</shape>
</item>
Android Asset Studio has an awesome tool to help you generate Patch 9 files: http://android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html
Android Asset Studio 有一个很棒的工具可以帮助您生成补丁 9 文件:http: //android-ui-utils.googlecode.com/hg/asset-studio/dist/nine-patches.html
Example primary xdpi png with padding before the tool:
Example secondary xdpi png with padding before the tool:
工具前带填充的主 xdpi png
示例:工具前带填充的
辅助 xdpi png 示例:
And the final output:
和最终输出:
回答by codingbubble
Just change the label <clip>
to <scale>
like this:
只需将标签更改<clip>
为<scale>
这样:
<scale android:scaleWidth="100%">
回答by Karan
As far as I know, this is not possible. Because internally ClipDrawable
(i.e. clip tag) cuts the given shape/drawable using canvas.clipRect()
. Btw, you can copy the ClipDrawable
source from hereand clip a particular path based on the progress level.
据我所知,这是不可能的。因为在内部ClipDrawable
(即剪辑标签)使用canvas.clipRect()
. 顺便说一句,您可以ClipDrawable
从这里复制源并根据进度级别剪辑特定路径。
回答by Neromancer
In order to solve the problem where the end graphics overlap themselves when the progress is very low, I've written an extension to the ProgressBar class that adds a fixed start offset to the progress bar, while otherwise functioning as normal.
为了解决进度非常低时最终图形重叠的问题,我为 ProgressBar 类编写了一个扩展,它为进度条添加了一个固定的起始偏移量,而其他方面则正常运行。
Just call 'setMaxWithPercentOffset()' or 'setMaxWithOffset()' rather than 'setMax()' passing in the value you want to add as a start offset to the progress bar.
只需调用 'setMaxWithPercentOffset()' 或 'setMaxWithOffset()' 而不是 'setMax()' 传递您想要作为开始偏移添加到进度条的值。
If anyone has solved this problem without requiring the start offset let me know!
如果有人在不需要开始偏移的情况下解决了这个问题,请告诉我!
/**
* This progress bar can be used when the progress bar end graphics are styled in some way.
* In this case, the progress bar must always have a small percentage of progress, otherwise
* the styled ends of the progress overlap each other.
*
*/
public class EndStyledProgressBar extends ProgressBar {
private static final int DEFAULT_START_OFFSET_PERCENT = 5;
private int mStartOffset;
private int mRealMax;
public EndStyledProgressBar(Context context) {
super(context);
commonConstructor();
}
public EndStyledProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
commonConstructor();
}
public EndStyledProgressBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
commonConstructor();
}
private void commonConstructor() {
mRealMax = super.getMax();
mStartOffset = 0;
setMaxWithPercentOffset(DEFAULT_START_OFFSET_PERCENT, mRealMax);
super.setProgress(super.getProgress() + mStartOffset);
super.setSecondaryProgress(super.getSecondaryProgress() + mStartOffset);
}
public void setProgress(int progress) {
super.setProgress(progress + mStartOffset);
}
public void setSecondaryProgress(int secondaryProgress) {
super.setSecondaryProgress(secondaryProgress + mStartOffset);
}
public int getProgress() {
int realProgress = super.getProgress();
return isIndeterminate() ? 0 : (realProgress - mStartOffset);
}
public int getSecondaryProgress() {
int realSecondaryProgress = super.getSecondaryProgress();
return isIndeterminate() ? 0 : (realSecondaryProgress - mStartOffset);
}
public int getMax() {
return mRealMax;
}
/**
* Don't call this, instead call setMaxWithPercentOffset() or setStartOffsetInPercent()
*
* @param max
*/
public void setMax(int max) {
super.setMax(max);
}
/**
* Sets a new max with a start offset (in percent) included.
*
* @param startOffsetInPercent start offset for the progress bar to avoid graphic errors.
*/
public void setMaxWithPercentOffset(int startOffsetInPercent, int max) {
mRealMax = max;
int startOffset = (mRealMax * startOffsetInPercent) / 100;
setMaxWithOffset(startOffset, max);
}
/**
* Sets a new max with a start offset included.
*
* @param startOffset start offset for the progress bar to avoid graphic errors.
*/
public void setMaxWithOffset(int startOffset, int max) {
mRealMax = max;
super.setMax(startOffset + max);
setStartOffset(startOffset);
super.setMax(startOffset + max);
}
/**
* Sets a new start offset different from the default of 5%
*
* @param startOffset start offset for the progress bar to avoid graphic errors.
*/
private void setStartOffset(int startOffset) {
int newStartOffset = startOffset;
// Ensure the start offset is not outside the range of the progress bar
if (newStartOffset < 0) newStartOffset = 0;
if (newStartOffset >= super.getMax()) newStartOffset = super.getMax();
// Apply the start offset difference
if (mStartOffset != newStartOffset) {
int diff = newStartOffset - mStartOffset;
super.setMax(super.getMax() + diff);
super.setProgress(super.getProgress() + diff);
super.setSecondaryProgress(super.getSecondaryProgress() + diff);
mStartOffset = newStartOffset;
}
}
}
回答by Konstantin Konopko
Final rounded both sides progress bar without 9-patch is:
android:progressDrawable="@drawable/progress_horizontal_green"
没有 9-patch 的最终四舍五入的双方进度条是:
android:progressDrawable="@drawable/progress_horizontal_green"
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%">
<shape>
<corners android:radius="5dip"/>
<solid android:color="#33FF33"/>
</shape>
</scale>
</item>