Android - 在 Lollipop 之前的设备上为 ProgressBar 着色
Android - Tinting ProgressBar on pre-Lollipop devices
我的应用程序的最低 API 级别是 19 (KitKat),并且包含一个水平布局 ProgressBar
。我正在使用 android:progressTint
属性将栏着色为自定义颜色。它在 Lollipop (API 21) 及更高版本上运行良好,但在以下版本(例如在 API 19 上)则不然;它以不同的颜色显示。原因是这个属性
is only used in API level 21 and higher
作为 Android 工作室状态。
所以我想知道什么是在 Lollipop 之前的设备上为 ProgressBar
着色的好选择。可以用 XML 在布局文件中制作吗?还是应该以不同的方式完成?
编辑 #1: 我的 ProgressBar 用于以百分比显示具体值,而不是用于指示我的布局正在加载。我想说清楚,因为在尝试了 Kuldeep Kulkarni 在下面写的内容之后,我的栏看起来像一个 material 加载指示器(当然在 Lollipop 设备上,在 KitKat 设备上没有任何可见结果)。
希望对您有所帮助。
试试这个:
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateTint="#F00"
android:indeterminateTintMode="src_in" />
您可以使用 ProgressBar indeterminateDrawable
方法包装 pre-Lollipop
。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Drawable drawableProgress = DrawableCompat.wrap(progressBar.getIndeterminateDrawable());
DrawableCompat.setTint(drawableProgress, ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(drawableProgress));
} else {
progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN);
}
感谢大家的建议! :)
对我有用的解决方案是使用 <layer-list>
根元素创建自定义可绘制 XML 文件。在那里,我使用原生 Android ID @android:id/background
和 @android:id/progress
定义了两层项目。在此之后,我可以定义我想要使用的形状和颜色资源。此解决方案类似于 this SO 问题上更受欢迎的答案。
我的 res/drawable/progressbar.xml
文件的内容:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="2dip" /> <!--optional-->
<gradient
android:angle="270"
android:endColor="@color/gray"
android:startColor="@color/gray" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="2dip" /> <!--optional-->
<gradient
android:angle="270"
android:endColor="@color/blue"
android:startColor="@color/blue" />
</shape>
</clip>
</item>
</layer-list>
在布局 XML 文件中为我的 ProgressBar
定义为 progressDrawable
:
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="0dp"
android:layout_height="@dimen/progress_bar_height"
android:progressDrawable="@drawable/progressbar" />
我没有机会在 API 19 以下进行测试,但在这个级别及以上它运行完美。
progress.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
这对我有用
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/progressBarBlue" />
然后在你的style.xml
定义progressBarBlue
<style name="progressBarWhite" parent="@style/Theme.AppCompat">
<item name="colorAccent">@color/blue</item>
</style>
如果你想以编程方式进行,试试这个
public static void setSeekbarTint(SeekBar seekbar, int color) {
PorterDuff.Mode porterDuffMode = PorterDuff.Mode.SRC_IN;
if (seekbar.getIndeterminateDrawable() != null)
seekbar.getIndeterminateDrawable().setColorFilter(color, porterDuffMode);
if (seekbar.getProgressDrawable() != null &&
seekbar.getProgressDrawable() instanceof LayerDrawable) {
LayerDrawable layerDrawable = (LayerDrawable) seekbar.getProgressDrawable();
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(android.R.id.background);
layerDrawable.setColorFilter(color, porterDuffMode);
seekbar.setProgressDrawable(layerDrawable);
gradientDrawable.setColorFilter(Color.WHITE, porterDuffMode);
} else if (seekbar.getProgressDrawable() != null &&
seekbar.getProgressDrawable() instanceof ClipDrawable) {
ClipDrawable clipDrawable = (ClipDrawable) seekbar.getProgressDrawable();
clipDrawable.setColorFilter(color, porterDuffMode);
seekbar.setProgressDrawable(clipDrawable);
}
}
我的应用程序的最低 API 级别是 19 (KitKat),并且包含一个水平布局 ProgressBar
。我正在使用 android:progressTint
属性将栏着色为自定义颜色。它在 Lollipop (API 21) 及更高版本上运行良好,但在以下版本(例如在 API 19 上)则不然;它以不同的颜色显示。原因是这个属性
is only used in API level 21 and higher
作为 Android 工作室状态。
所以我想知道什么是在 Lollipop 之前的设备上为 ProgressBar
着色的好选择。可以用 XML 在布局文件中制作吗?还是应该以不同的方式完成?
编辑 #1: 我的 ProgressBar 用于以百分比显示具体值,而不是用于指示我的布局正在加载。我想说清楚,因为在尝试了 Kuldeep Kulkarni 在下面写的内容之后,我的栏看起来像一个 material 加载指示器(当然在 Lollipop 设备上,在 KitKat 设备上没有任何可见结果)。
希望对您有所帮助。 试试这个:
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateTint="#F00"
android:indeterminateTintMode="src_in" />
您可以使用 ProgressBar indeterminateDrawable
方法包装 pre-Lollipop
。
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Drawable drawableProgress = DrawableCompat.wrap(progressBar.getIndeterminateDrawable());
DrawableCompat.setTint(drawableProgress, ContextCompat.getColor(getContext(), android.R.color.holo_green_light));
progressBar.setIndeterminateDrawable(DrawableCompat.unwrap(drawableProgress));
} else {
progressBar.getIndeterminateDrawable().setColorFilter(ContextCompat.getColor(getContext(), android.R.color.holo_green_light), PorterDuff.Mode.SRC_IN);
}
感谢大家的建议! :)
对我有用的解决方案是使用 <layer-list>
根元素创建自定义可绘制 XML 文件。在那里,我使用原生 Android ID @android:id/background
和 @android:id/progress
定义了两层项目。在此之后,我可以定义我想要使用的形状和颜色资源。此解决方案类似于 this SO 问题上更受欢迎的答案。
我的 res/drawable/progressbar.xml
文件的内容:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="2dip" /> <!--optional-->
<gradient
android:angle="270"
android:endColor="@color/gray"
android:startColor="@color/gray" />
</shape>
</item>
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="2dip" /> <!--optional-->
<gradient
android:angle="270"
android:endColor="@color/blue"
android:startColor="@color/blue" />
</shape>
</clip>
</item>
</layer-list>
在布局 XML 文件中为我的 ProgressBar
定义为 progressDrawable
:
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="0dp"
android:layout_height="@dimen/progress_bar_height"
android:progressDrawable="@drawable/progressbar" />
我没有机会在 API 19 以下进行测试,但在这个级别及以上它运行完美。
progress.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
这对我有用
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:theme="@style/progressBarBlue" />
然后在你的style.xml
定义progressBarBlue
<style name="progressBarWhite" parent="@style/Theme.AppCompat">
<item name="colorAccent">@color/blue</item>
</style>
如果你想以编程方式进行,试试这个
public static void setSeekbarTint(SeekBar seekbar, int color) {
PorterDuff.Mode porterDuffMode = PorterDuff.Mode.SRC_IN;
if (seekbar.getIndeterminateDrawable() != null)
seekbar.getIndeterminateDrawable().setColorFilter(color, porterDuffMode);
if (seekbar.getProgressDrawable() != null &&
seekbar.getProgressDrawable() instanceof LayerDrawable) {
LayerDrawable layerDrawable = (LayerDrawable) seekbar.getProgressDrawable();
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(android.R.id.background);
layerDrawable.setColorFilter(color, porterDuffMode);
seekbar.setProgressDrawable(layerDrawable);
gradientDrawable.setColorFilter(Color.WHITE, porterDuffMode);
} else if (seekbar.getProgressDrawable() != null &&
seekbar.getProgressDrawable() instanceof ClipDrawable) {
ClipDrawable clipDrawable = (ClipDrawable) seekbar.getProgressDrawable();
clipDrawable.setColorFilter(color, porterDuffMode);
seekbar.setProgressDrawable(clipDrawable);
}
}