Android - Tinting ProgressBar на устройствах с предустановленной Lollipop
Минимальный уровень API для моего приложения - 19 (KitKat) и содержит макет с горизонтальным ProgressBar
. Я использую атрибут android:progressTint
чтобы подкрасить панель к пользовательскому цвету. Он отлично работает на Lollipop (API 21) и выше, но ниже (например, на API 19) это не так; он появляется в другом цвете. Причина в том, что этот атрибут
используется только в API уровня 21 и выше
как заявляет Android Studio.
Поэтому мне интересно, что может быть хорошей альтернативой тонированию ProgressBar
на устройствах с предварительным Lollipop. Может ли оно быть сделано внутри файла макета с XML? Или это должно быть сделано по-другому?
EDIT # 1: My ProgressBar используется для отображения конкретных значений в процентах, а не для указания того, что мой макет загружается. Я хочу сделать это ясно, потому что, попробовав то, что написал Kuldeep Kulkarni ниже, мой бар выглядел как индикатор загрузки материала (конечно, на устройстве Lollipop, а не на видимом результате на устройстве KitKat).
Ответы
Ответ 1
Спасибо за предложения от всех! :)
Решение, которое работает для меня, заключается в создании пользовательского извлекаемого XML файла с корневым элементом <layer-list>
. Там я определяю два слоя с собственными идентификаторами Android @android:id/background
и @android:id/progress
. После этого я могу определить формы и цветовые ресурсы, которые я хотел бы использовать. Это решение похоже на более популярный ответ на этот вопрос 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>
Определяется как progressDrawable
для моего ProgressBar
в XML файле макета:
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="0dp"
android:layout_height="@dimen/progress_bar_height"
android:progressDrawable="@drawable/progressbar" />
У меня не было возможности проверить его ниже API 19, но на этом уровне и выше он отлично работает.
Ответ 2
Вы можете обмотать метод 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);
}
Ответ 3
progress.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN);
Ответ 4
Это работает для меня
<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>
Ответ 5
Я использую этого плохого мальчика широко, это очень хорошо
Ответ 6
Если вы хотите сделать это программно, попробуйте это
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);
}
}
Ответ 7
Я надеюсь, что это поможет вам. Попробуй это:
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true"
android:indeterminateTint="#F00"
android:indeterminateTintMode="src_in" />