如何在Android中更改进度条的进度颜色
我在我的Android应用程序中使用水平进度条,我想改变其进度颜色(默认为黄色)。 我怎样才能使用code
(而不是XML)?
对不起,这不是答案,但是是什么推动了从代码中设置它的要求? 如果定义正确, .setProgressDrawable
应该可以正常工作
<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="270" /> </shape> </item> <item android:id="@android:id/secondaryProgress"> <clip> <shape> <corners android:radius="5dip" /> <gradient android:startColor="#80ffd300" android:centerColor="#80ffb600" android:centerY="0.75" android:endColor="#a0ffcb00" android:angle="270" /> </shape> </clip> </item> <item android:id="@android:id/progress"> <clip> <shape> <corners android:radius="5dip" /> <gradient android:startColor="@color/progress_start" android:endColor="@color/progress_end" android:angle="270" /> </shape> </clip> </item> </layer-list>
对于水平ProgressBar,也可以使用ColorFilter
,如下所示:
progressBar.getProgressDrawable().setColorFilter( Color.RED, android.graphics.PorterDuff.Mode.SRC_IN);
如果progressBar不确定,则使用getIndeterminateDrawable()
而不是getProgressDrawable()
。
由于棒棒糖(API 21),你可以设置进度色彩:
progressBar.setProgressTintList(ColorStateList.valueOf(Color.RED));
对于我不确定的进度条(微调),我只是在drawable上设置一个颜色过滤器。 很好,只是一条线。
将颜色设置为红色的示例:
ProgressBar spinner = new android.widget.ProgressBar( context, null, android.R.attr.progressBarStyle); spinner.getIndeterminateDrawable().setColorFilter(0xFFFF0000, android.graphics.PorterDuff.Mode.MULTIPLY);
这不是编程,但我认为它可以帮助很多人! 我尝试了很多,最有效的方法是将这些行添加到我的ProgressBar的.xml文件中:
android:indeterminate="true" android:indeterminateTintMode="src_atop" android:indeterminateTint="@color/secondary"
所以最后这个代码为我做了:
<ProgressBar android:id="@+id/progressBar" style="?android:attr/progressBarStyleLarge" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_marginTop="50dp" android:layout_marginBottom="50dp" android:visibility="visible" android:indeterminate="true" android:indeterminateTintMode="src_atop" android:indeterminateTint="@color/secondary">
此解决方案适用于API 21+
这是一个老问题,但是在这里没有提到使用主题。 如果您的默认主题使用的是AppCompat
,则ProgressBar
的颜色将为您定义的colorAccent
。
改变colorAccent
也会改变你的ProgressBar
的颜色,但是改变也反映在多个地方。 所以,如果您想为特定的PregressBar
创建不同的颜色,您可以通过将主题应用于ProgressBar
:
-
扩展您的默认主题并覆盖
colorAccent
<style name="AppTheme.WhiteAccent"> <item name="colorAccent">@color/white</item> <!-- Whatever color you want--> </style>
-
并在
ProgressBar
添加android:theme
属性:android:theme="@style/AppTheme.WhiteAccent"
所以它会看起来像这样:
<ProgressBar android:id="@+id/loading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:padding="10dp" android:theme="@style/AppTheme.WhiteAccent" />
所以你只是改变你的特定ProgressBar
的colorAccent
。
注意 :使用style
将不起作用。 您只需要使用android:theme
。 您可以在这里找到更多使用主题: https : //plus.google.com/u/0/+AndroidDevelopers/posts/JXHKyhsWHAH
根据一些建议,你可以指定一个形状,并用一种颜色剪裁,然后设置它。 我有这个编程的工作。 我就是这么做的
首先确保您导入绘图库
import 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);
在修改默认进度栏的外观时,遇到同样的问题。 这里有一些更多的信息,希望可以帮助人们:)
- xml文件的名称只能包含字符:
a-z0-9_.
(即没有首都!) - 为了引用你的“drawable”,它是
R.drawable.filename
- 要覆盖默认外观,您可以使用
myProgressBar.setProgressDrawable(...)
,但是您不需要将您的自定义布局引用为R.drawable.filename
,则需要将其作为Drawable
进行检索:Resources res = getResources(); myProgressBar.setProgressDrawable(res.getDrawable(R.drawable.filename);
- 您需要在设置进度/二级进度/最大值之前设置样式(之后为我设置一个“空”进度条)
如果不确定:
((ProgressBar)findViewById(R.id.progressBar)) .getIndeterminateDrawable() .setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
现在在2016年,我发现一些pre-Lollipop设备不尊重colorAccent
设置,所以我现在对于所有API的最终解决方案如下:
// fixes pre-Lollipop progressBar indeterminateDrawable tinting if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { Drawable wrapDrawable = DrawableCompat.wrap(mProgressBar.getIndeterminateDrawable()); DrawableCompat.setTint(wrapDrawable, ContextCompat.getColor(getContext(), android.R.color.holo_green_light)); mProgressBar.setIndeterminateDrawable(DrawableCompat.unwrap(wrapDrawable)); } else { mProgressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN); }
对于奖励积分,它不使用任何弃用的代码。 尝试一下!
在这个答案中可能有一件事没有被提及:
如果您的主题是从Theme.AppCompat
继承的,则ProgressBar
将假定您在主题中定义为"colorAccent"
的颜色。
所以,使用..
<item name="colorAccent">@color/custom_color</item>
..将自动将ProgressBar的颜色着色到@color/custom_color
。
这对我工作:
<ProgressBar android:indeterminateTint="#d60909" ... />
我如何在水平ProgressBar中做到这一点:
LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable(); Drawable progressDrawable = layerDrawable.findDrawableByLayerId(android.R.id.progress); progressDrawable.setColorFilter(color, PorterDuff.Mode.SRC_IN);
android:progressTint="#ffffff"
如果你继承了一个基础主题,那么主题解决方案还有一个小的功能,所以对于应用程序的紧凑,你的主题应该是:
<style name="AppTheme.Custom" parent="@style/Theme.AppCompat"> <item name="colorAccent">@color/custom</item> </style>
然后在进度条主题中进行设置
<ProgressBar android:id="@+id/progressCircle_progressBar" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:theme="@style/AppTheme.Custom" android:indeterminate="true"/>
这个解决方案为我工作:
<style name="Progressbar.White" parent="AppTheme"> <item name="colorControlActivated">@color/white</item> </style> <ProgressBar android:layout_width="@dimen/d_40" android:layout_height="@dimen/d_40" android:indeterminate="true" android:theme="@style/Progressbar.White"/>
对于我使用的水平样式ProgressBar:
import android.widget.ProgressBar; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.ClipDrawable; import android.view.Gravity; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; public void setColours(ProgressBar progressBar, int bgCol1, int bgCol2, int fg1Col1, int fg1Col2, int value1, int fg2Col1, int fg2Col2, int value2) { //If solid colours are required for an element, then set //that elements Col1 param s the same as its Col2 param //(eg fg1Col1 == fg1Col2). //fgGradDirection and/or bgGradDirection could be parameters //if you require other gradient directions eg LEFT_RIGHT. GradientDrawable.Orientation fgGradDirection = GradientDrawable.Orientation.TOP_BOTTOM; GradientDrawable.Orientation bgGradDirection = GradientDrawable.Orientation.TOP_BOTTOM; //Background GradientDrawable bgGradDrawable = new GradientDrawable( bgGradDirection, new int[]{bgCol1, bgCol2}); bgGradDrawable.setShape(GradientDrawable.RECTANGLE); bgGradDrawable.setCornerRadius(5); ClipDrawable bgclip = new ClipDrawable( bgGradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); bgclip.setLevel(10000); //SecondaryProgress GradientDrawable fg2GradDrawable = new GradientDrawable( fgGradDirection, new int[]{fg2Col1, fg2Col2}); fg2GradDrawable.setShape(GradientDrawable.RECTANGLE); fg2GradDrawable.setCornerRadius(5); ClipDrawable fg2clip = new ClipDrawable( fg2GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); //Progress GradientDrawable fg1GradDrawable = new GradientDrawable( fgGradDirection, new int[]{fg1Col1, fg1Col2}); fg1GradDrawable.setShape(GradientDrawable.RECTANGLE); fg1GradDrawable.setCornerRadius(5); ClipDrawable fg1clip = new ClipDrawable( fg1GradDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); //Setup LayerDrawable and assign to progressBar Drawable[] progressDrawables = {bgclip, fg2clip, fg1clip}; LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables); progressLayerDrawable.setId(0, android.R.id.background); progressLayerDrawable.setId(1, android.R.id.secondaryProgress); progressLayerDrawable.setId(2, android.R.id.progress); //Copy the existing ProgressDrawable bounds to the new one. Rect bounds = progressBar.getProgressDrawable().getBounds(); progressBar.setProgressDrawable(progressLayerDrawable); progressBar.getProgressDrawable().setBounds(bounds); // setProgress() ignores a change to the same value, so: if (value1 == 0) progressBar.setProgress(1); else progressBar.setProgress(0); progressBar.setProgress(value1); // setSecondaryProgress() ignores a change to the same value, so: if (value2 == 0) progressBar.setSecondaryProgress(1); else progressBar.setSecondaryProgress(0); progressBar.setSecondaryProgress(value2); //now force a redraw progressBar.invalidate(); }
一个示例调用将是:
setColours(myProgressBar, 0xff303030, //bgCol1 grey 0xff909090, //bgCol2 lighter grey 0xff0000FF, //fg1Col1 blue 0xffFFFFFF, //fg1Col2 white 50, //value1 0xffFF0000, //fg2Col1 red 0xffFFFFFF, //fg2Col2 white 75); //value2
如果您不需要“二级进度”,只需将value2设置为value1即可。
发布,以添加有关PaulieG的答案 ,因为ateiob要求我解释一些东西的信息…
不幸的是,当我提出解决方案的编辑时,很久以前,我不记得所有的细节。
我可以说,在ProgressBar
代码中存在(或者至少是在编写本文的时候,当我看到当前版本的Android源代码时)BUG /问题/优化,忽略了将进度设置为值的尝试它已经在。
- 即如果进度= 45,并且您尝试将其设置为45,则代码将不执行任何操作,并且不会重新绘制进度 。
调用ProgressBar.setProgressDrawable()
,你的进度条将是空白的(因为你改变了drawable部分)。
这意味着你需要设置进度,并重新绘制。 但是,如果您只将进度设置为保留的值,那么它将不会执行任何操作。
您必须先将其设置为0,然后再将其设置为“旧”值,并重新绘制条。
所以总结一下:
- 保留“旧”的进度值
- 更新绘图/颜色(使栏变空白)
- 重置进度到0(否则下一行什么都不做)
- 重置进度到“旧”值(修复栏)
- 废止
下面是我有这样做的方法 – 我希望它是有用的。 我不是100%确定为什么我从onResume()
调用它 – 这可能是重要的,或不相关的:
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的解决方案,我认为这是一个类似的解决方法,手动设置“进展”抵消(我不记得确切)。 无论哪种情况,上面的代码都适合你。
对不起,如果我不记得所有的细节 – 这就是为什么我试图编辑答案。 希望这可以帮助…
ProgressBar bar; private Handler progressBarHandler = new Handler(); GradientDrawable progressGradientDrawable = new GradientDrawable( GradientDrawable.Orientation.LEFT_RIGHT, new int[]{ 0xff1e90ff,0xff006ab6,0xff367ba8}); ClipDrawable progressClipDrawable = new ClipDrawable( progressGradientDrawable, Gravity.LEFT, ClipDrawable.HORIZONTAL); Drawable[] progressDrawables = { new ColorDrawable(0xffffffff), progressClipDrawable, progressClipDrawable}; LayerDrawable progressLayerDrawable = new LayerDrawable(progressDrawables); int status = 0; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // TODO Auto-generated method stub setContentView(R.layout.startup); bar = (ProgressBar) findViewById(R.id.start_page_progressBar); bar.setProgress(0); bar.setMax(100); progressLayerDrawable.setId(0, android.R.id.background); progressLayerDrawable.setId(1, android.R.id.secondaryProgress); progressLayerDrawable.setId(2, android.R.id.progress); bar.setProgressDrawable(progressLayerDrawable); }
这帮助我通过代码将自定义颜色设置为进度条。 希望它有帮助
将此自定义样式应用于进度栏。
<style name="customProgress" parent="@android:style/Widget.ProgressBar.Small"> <item name="android:indeterminateDrawable">@drawable/progress</item> <item name="android:duration">40</item> <item name="android:animationCache">true</item> <item name="android:drawingCacheQuality">low</item> <item name="android:persistentDrawingCache">animation</item> </style>
@ drawable / progress.xml –
<?xml version="1.0" encoding="utf-8"?> <animated-rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/spinner_white" android:pivotX="50%" android:pivotY="50%" />
使用这种类型的图像的进度条。
为了更好的结果,你可以使用多个进度图像。 而且请不要犹豫,使用图像,因为Android平台本身使用进度条的图像。 代码是从sdk中提取的:)
根据muhammad-adil建议的SDK版本21和更高版本
android:indeterminateTint="@color/orange"
在XML Works中对我来说很简单。
Horizontal ProgressBar
使用可绘制的rectangle shape
作为背景, ClipDrawable
从rectangle shape
构建为进度(主要和次要)。 着色会将颜色更改为某种色彩。 如果你想分别为所有三个有针对性的颜色 ,那么你可以使用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
,可绘制图层的顺序很重要。 第一个drawable应该是背景。 根据我的实验,切换ID不起作用。 如果您将填充设置为progressbar
则此方法无效。 如果你需要填充,那么你可以使用容器的进度条,如LinearLayout
。
使用attr这么简单,如果你正在处理multistyle应用程序:
试试这个方法:
声明属性attrs.xml下面
<attr name="circularProgressTheme" format="reference"></attr>
将下面的代码粘贴到styles.xml中
<style name="ProgressThemeWhite" parent="ThemeOverlay.AppCompat.Light"> <item name="colorAccent">#FF0000</item> </style> <style name="circularProgressThemeWhite"> <item name="android:theme">@style/ProgressThemeWhite</item> </style> <style name="AppTheme" parent="Theme.AppCompat.NoActionBar"> <item name="circularProgressTheme">@style/circularProgressThemeWhite</item> </style>
使用下面的进度条
<ProgressBar style="?attr/circularProgressTheme" android:id="@+id/commonProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="visible"/>
以下是以编程方式更改ProgressBar颜色的代码。
ProgressBar progressBar = (ProgressBar) findViewById(R.id.pb_listProgressBar); int colorCodeDark = Color.parseColor("#F44336"); progressBar.setIndeterminateTintList(ColorStateList.valueOf(colorCodeDark));
水平进度条定制材质风格:
改变背景的颜色和水平进度条的进度。
<style name="MyProgressBar" parent="@style/Widget.AppCompat.ProgressBar.Horizontal"> <item name="android:progressBackgroundTint">#69f0ae</item> <item name="android:progressTint">#b71c1c</item> <item name="android:minWidth">200dp</item> </style>
通过设置样式属性将其应用于进度条,对于自定义材质样式和自定义进度条,请查看http://www.zoftino.com/android-progressbar-and-custom-progressbar-examples
这对我来说是一个简单的解决方案。
progressDialog.setMessage( Html.fromHtml("<font color='white'>" + Message + "</font>"));