我在我的Android应用程序中使用水平进度条,我想改变它的进度颜色(默认为黄色)。我如何使用代码(而不是XML)做到这一点?
当前回答
发布了关于PaulieG的答案的补充信息,因为ateiob让我解释一些事情…
我可以说,在ProgressBar代码中存在(或者至少是,当我查看当前版本的Android源代码时)一个错误/问题/优化,忽略了将进度设置为已经存在的值的尝试。
例如,如果progress = 45,而你试图将其设置为45,代码将什么都不做,也不会重绘进度。
调用ProgressBar.setProgressDrawable()后,你的进度条将是空白的(因为你改变了可绘制的部分)。
这意味着你需要设置进度,并重新绘制它。但是如果您只是将进度设置为保留值,它将什么也不做。
您必须先将其设置为0,然后再次设置为“旧”值,然后条将重新绘制。
总结一下:
保留“旧的”进度值 更新可绘制/颜色(使栏空白) 将进度重置为0(否则下一行不执行任何操作) 将进度重置为“旧”值(修复条) 无效
下面是一个方法,我有这样做:
protected void onResume()
{
super.onResume();
progBar = (ProgressBar) findViewById(R.id.progress_base);
int oldProgress = progBar.getProgress();
// define new drawable/colour
final float[] roundedCorners = new float[]
{ 5, 5, 5, 5, 5, 5, 5, 5 };
ShapeDrawable shape = new ShapeDrawable(new RoundRectShape(
roundedCorners, null, null));
String MyColor = "#FF00FF";
shape.getPaint().setColor(Color.parseColor(MyColor));
ClipDrawable clip = new ClipDrawable(shape, Gravity.LEFT,
ClipDrawable.HORIZONTAL);
progBar.setProgressDrawable(clip);
progBar.setBackgroundDrawable(getResources().getDrawable(
android.R.drawable.progress_horizontal));
// work around: setProgress() ignores a change to the same value
progBar.setProgress(0);
progBar.setProgress(oldProgress);
progBar.invalidate();
}
至于HappyEngineer的解决方案,我认为它是一个类似的解决方案,手动设置“进度”偏移量。无论哪种情况,上面的代码都应该适用于您。
其他回答
根据一些建议,你可以指定一个形状和可剪切的颜色,然后设置它。我让它以编程的方式工作。我就是这么做的。
首先确保导入了可绘制库。
进口android.graphics.drawable。*;
然后使用类似于下面的代码;
ProgressBar pg = (ProgressBar)row.findViewById(R.id.progress);
final float[] roundedCorners = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 };
pgDrawable = new ShapeDrawable(new RoundRectShape(roundedCorners, null,null));
String MyColor = "#FF00FF";
pgDrawable.getPaint().setColor(Color.parseColor(MyColor));
ClipDrawable progress = new ClipDrawable(pgDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL);
pg.setProgressDrawable(progress);
pg.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.progress_horizontal));
pg.setProgress(45);
所有接口
如果使用所有的API只创建主题的样式
style.xml
<resources>
//...
<style name="progressBarBlue" parent="@style/Theme.AppCompat">
<item name="colorAccent">@color/blue</item>
</style>
</resources>
在进行中使用
<ProgressBar
...
android:theme="@style/progressBarBlue" />
空气污染指数21或以上
如果在API级别21及以上使用,请使用以下代码:
<ProgressBar
//...
android:indeterminate="true"
android:indeterminateTintMode="src_atop"
android:indeterminateTint="@color/secondary"/>
你可以尝试改变你的风格,主题,或使用android:indeterminateTint="@color/yourColor"任何你想要的地方,但只有一种方法来做,将工作在任何android SKD版本:
如果你的进度条不是不确定的,请使用:
progressBar.getProgressDrawable().setColorFilter(ContextCompat.getColor(context, R.color.yourColor), PorterDuff.Mode.SRC_IN );
如果进度条不确定,请使用:
progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), R.color.yourColor), PorterDuff.Mode.SRC_IN );
Android真是一团糟!
更改水平进度条颜色(kotlin):
fun tintHorizontalProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
progress.progressTintList = ColorStateList.valueOf(color)
} else{
val layerDrawable = progress.progressDrawable as? LayerDrawable
val progressDrawable = layerDrawable?.findDrawableByLayerId(android.R.id.progress)
progressDrawable?.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
}
}
更改不确定的ProgressBar颜色:
fun tintIndeterminateProgress(progress: ProgressBar, @ColorInt color: Int = ContextCompat.getColor(progress.context, R.color.colorPrimary)){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
progress.indeterminateTintList = ColorStateList.valueOf(color)
} else {
(progress.indeterminateDrawable as? LayerDrawable)?.apply {
if (numberOfLayers >= 2) {
setId(0, android.R.id.progress)
setId(1, android.R.id.secondaryProgress)
val progressDrawable = findDrawableByLayerId(android.R.id.progress).mutate()
progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
}
}
}
}
它最终正常地着色pre-lollipop progressBars
水平ProgressBar使用矩形形状绘制背景,ClipDrawable从矩形形状构建的进展(主要和次要)。着色将颜色改变为某种色调。如果你想分别为这三种颜色设置目标颜色,你可以使用ProgressBar.setProgressDrawable(),如下所示:
LayerDrawable progressBarDrawable = new LayerDrawable(
new Drawable[]{
new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
new int[]{Color.parseColor("#ff0000ff"),Color.parseColor("#ff0000ff")}),
new ClipDrawable(
new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
new int[]{Color.parseColor("#ff00ff00"),Color.parseColor("#ff00ff00")}),
Gravity.START,
ClipDrawable.HORIZONTAL),
new ClipDrawable(
new GradientDrawable(GradientDrawable.Orientation.TOP_BOTTOM,
new int[]{Color.parseColor("#ffff0000"),Color.parseColor("#ffff0000")}),
Gravity.START,
ClipDrawable.HORIZONTAL)
});
progressBarDrawable.setId(0,android.R.id.background);
progressBarDrawable.setId(1,android.R.id.secondaryProgress);
progressBarDrawable.setId(2,android.R.id.progress);
((ProgressBar)findViewById(R.id.progressBar)).setProgressDrawable(progressBarDrawable);
注意,在初始化LayerDrawable时,可绘制层的顺序很重要。首先绘制的应该是背景。根据我的实验,切换id是行不通的。如果你将填充设置为progressbar,那么这种方法将不起作用。如果你需要填充,那么你可以使用一个容器的进度条,如线性布局。
推荐文章
- 如何解决“丢失的PendingIntent可变性标志”在android api 30+ lint警告?
- 我怎么能修复“意外元素<查询>发现<manifest>”错误?
- Android房间-自动生成新插入行的id
- Android Studio在哪里保存ProGuard映射文件?
- 我如何从资产文件夹解析一个本地JSON文件到一个ListView?
- Android 4.4 (KitKat)上的Android Gallery为Intent返回不同的URI。ACTION_GET_CONTENT
- 移除动作栏下面的阴影
- 如何在线性布局的一侧绘制边界?
- 找到可移动SD卡的位置
- 用于自定义视图的attrs.xml中的同名属性
- IntelliJ IDEA with Junit 4.7”!!JUnit 3.8或更高版本:
- 如何确定Gradle的版本?
- 在android studio中不能小写按钮文本
- 安装在控制台显示错误:安装失败,冲突的提供程序
- 如何在Android中制作倒计时计时器?