I'm trying to change the color of the customized ProgressBar dynamically with Java.
This is the implementation of the ProgressBar on the main layout:
[activity_main.xml]
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:progressDrawable="@drawable/custom_progress"
android:background="@drawable/custom_progress_bar"
android:max="100"
android:progress="80" />
I have created two seperate drawables to customize the progress bar as follows:
[custom_progress_bar.xml & custom_progress.xml]
<!-- custom_progress_bar.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="@color/white"/>
</shape>
</item>
</layer-list>
<!-- custom_progress.xml -->
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/progress_solid">
<clip>
<shape android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="@color/progress"/>
</shape>
</clip>
</item>
</layer-list>
Here is the Java code that is supposed to change the progress bar from green (@color/progress) to red:
[MainActivity.java]
LayerDrawable layerDrawable = (LayerDrawable) ContextCompat.getDrawable(this, R.drawable.custom_progress);
ClipDrawable progressSolid = (ClipDrawable) layerDrawable.findDrawableByLayerId(R.id.progress_solid);
GradientDrawable gradientDrawable = new GradientDrawable();
gradientDrawable.setColor(Color.RED);
progressSolid.setDrawable(gradientDrawable);
progressBar.invalidate();
This is the theme, (I've set out both themes to be exactly the same):
[themes.xml & themes.xml (night)]
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Base.Theme.CountdownCalender" parent="Theme.Material3.DayNight.NoActionBar">
<!-- Customizing the light theme here. -->
<item name="colorPrimaryVariant">@color/black</item>
<item name="colorPrimaryDark">@color/black</item>
<item name="colorPrimary">@color/progress</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorSurface">@color/white</item>
</style>
<style name="Theme.CountdownCalender" parent="Base.Theme.CountdownCalender" />
<style name="CalenderViewDateCustomText">
<item name="colorControlActivated">@drawable/selected_day</item>
<item name="android:textColor">@color/white</item>
<item name="android:weekDayTextAppearance">@color/accent</item>
</style>
</resources>
The unwanted result: unwanted result
This is not the result I want. I want it to change to red as the Java code shows. What am I missing? My co-pilot chatbot is not helping.. I'd really appreciate the help. Thank you in advance.
SOLUTION: Turns out I just needed these few lines:
LayerDrawable layerDrawable = (LayerDrawable) progressBar.getProgressDrawable();
Drawable progressFill = layerDrawable.getDrawable(1);
progressFill.setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
and replace the previous code. I'm yet to research what the last line is exactly, but it works as shown below: desired output
Let's suppose
progressis a variable holding a reference to your progressbar then you can use the following Java code to change the progress color programmatically:equivalent in Kotlin:
setTintLintis a static function fromDrawableCompat. The color should be a valid ColorRes resource. Hope this helps.