Android - Тонирование ProgressBar на устройствах до Lollipop

Минимальный уровень API моего приложения - 19 (KitKat), и он содержит макет с горизонтальным ProgressBar. Я использую атрибут android:progressTint, чтобы придать полосе собственный цвет. Он довольно хорошо работает на Lollipop (API 21) и выше, но ниже (например, в API 19) - нет; он отображается другим цветом. Причина в том, что этот атрибут

используется только в API уровня 21 и выше

как заявляет Android Studio.

Так что мне интересно, что может быть хорошей альтернативой для тонировки ProgressBar на устройствах до Lollipop. Можно ли сделать это внутри файла макета с помощью XML? Или это нужно сделать по-другому?


РЕДАКТИРОВАТЬ №1: My ProgressBar используется для отображения конкретных значений в процентах, а не для указания того, что мой макет загружается. Я хочу прояснить это, потому что после того, как я попробовал то, что написал ниже Калдип Кулкарни, моя полоса выглядела как индикатор загрузки материала (конечно, на устройстве Lollipop, а на устройстве KitKat не было видимого результата).


person Geryson    schedule 06.04.2017    source источник
comment
progressTint у меня не работает на Lollipop, кто-нибудь знает причину, по которой   -  person user3701188    schedule 22.02.2019


Ответы (6)


Вы можете обернуть 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);
}
person Satan Pandeya    schedule 06.04.2017
comment
Я пробовал его использовать, код тоже запускается, но никаких видимых результатов ... также см. Правку вопроса. - person Geryson; 06.04.2017
comment
Вам нужно setProgressDrawable - person offset; 20.09.2018

Спасибо за предложения от всех! :)

Решение, которое мне подходит, - создать настраиваемый файл 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, но на этом уровне и выше он работает отлично.

person Geryson    schedule 11.09.2017

Это работает для меня

<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>
person Dennis Mwagiru    schedule 03.07.2019

Если вы хотите сделать это программно, попробуйте это

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);
        }
}
person Jahnavi Nandamuri    schedule 30.08.2019

Я надеюсь, что это поможет вам. Попробуй это:

<ProgressBar
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:indeterminate="true"
        android:indeterminateTint="#F00"
        android:indeterminateTintMode="src_in" />
person Kuldeep Kulkarni    schedule 06.04.2017
comment
Извините, это работает не так, как хотелось бы - атрибут indeterminateTint использует основной цвет приложения, который отличается от цвета, который я хочу использовать; он также работает с API 21 и выше. - person Geryson; 06.04.2017
comment
Это несовместимо с pre-Lollipop, как это требуется. - person Patrick Boos; 31.08.2017

person    schedule
comment
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и / или почему он решает проблему, улучшит долгосрочную ценность ответа. - person Nic3500; 05.08.2018
comment
Это решение сработало для меня лучше, чем одно из самых популярных на данный момент. - person Urban; 26.10.2018
comment
Сейчас это устарело - person Jake; 08.08.2019