Styling indeterminate horizontal progress bar on android - android

Styling determinate progress bar is easy, there are many tutorials to achieve that. This is on I'm using:
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="#drawable/progress_background"
android:progressDrawable="#drawable/progress"
android:id="#+id/progressBar" />
Drawable progress_background.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/progress">
<clip>
<shape>
<solid android:color="#color/colorAccent" />
<corners android:radius="4dp" />
</shape>
</clip>
</item>
</layer-list>
It looks like this:
But when progress is not available yet, I'd like to use indeterminate one. So I tried:
<ProgressBar
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:background="#drawable/progress_background"
android:progressDrawable="#drawable/progress"
android:indeterminateTint="#color/colorAccent"
android:indeterminateTintMode="src_in"
android:indeterminate="true"
android:id="#+id/progressBar" />
But indeterminate progress is not stretched to bar height:
I tried to style it using drawable file as well but it looked like broken determinate progress bar (filling from 0 to 100 all over again).
Desired indeterminate progress bar should look like regular one but with 8dp height and rounded corners.

Default indeterminate progress bar animation use a non 9-patch pngs. So it can't be stretched over your 8dp height progress bar. You should add android:indeterminateDrawable with custom animation:
<animation-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="#drawable/progressbar_indeterminate1" android:duration="50" />
<item android:drawable="#drawable/progressbar_indeterminate2" android:duration="50" />
<item android:drawable="#drawable/progressbar_indeterminate3" android:duration="50" />
...
<item android:drawable="#drawable/progressbar_indeterminateX" android:duration="50" />
</animation-list>
Then make drawables to animate it like this (it can be xml or image or 9-patch):
Animation frame 1
Animation frame 2
Never versions of android (api21+) use AnimatedVectorDrawable for indeterminate ProgressBar.

I saw that a lot of people are looking on this post so I thought that I should edit it and share an example:
Note (this example is not complete, it's still in progress but I guess it's a starting point)
GitHub: Github Example
The important part in this example is below: Create in drawable a xml file custom_progress_bar_horizontal.xml and add the content below.
<?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>
<padding
android:bottom="3dip"
android:top="3dip"
android:left="3dip"
android:right="3dip"/>
<corners
android:radius="5dip" />
<gradient
android:startColor="#2a2b2f"
android:centerColor="#2a2b2f"
android:centerY="0.50"
android:endColor="#2a2b2f"
android:angle="270" />
</shape>
</item>
<item
android:id="#android:id/progress">
<clip>
<shape>
<corners
android:radius="5dip" />
<gradient
android:startColor="#ff0e75af"
android:endColor="#ff1997e1"
android:angle="90" />
</shape>
</clip>
</item>
</layer-list>
Add the following code in styles.xml
<style name="CustomProgressBar" parent="android:Widget.ProgressBar.Horizontal">
<item name="android:indeterminateOnly">false</item>
<item name="android:progressDrawable">#drawable/custom_progress_bar_horizontal</item>
<item name="android:minHeight">10dip</item>
<item name="android:maxHeight">20dip</item>
</style>
After you have added the style in your activity layout add:
<ProgressBar
android:id="#+id/customProgress"
style="#style/CustomProgressBar"
android:layout_width="match_parent"/>
The progress dispaly below in a frame it's a little tricky because you need to extend the ProgressBar class and make the changes there.
I will leave here some examples and notify when I will add them in my github project.
Great example if you want to disaply the progress in your way: NumberProgressBar
Other progress bar examples:
Custom progress bar 1
Custom progress bar 2
For more detail visit here. Android horizontal progress bar?

You know, android has a View named: LinearProgressIndicator
you can have indeterminate animation in the horizontal progress bar with that.
<com.google.android.material.progressindicator.LinearProgressIndicator
android:layout_width="280dp"
android:layout_height="12dp"
android:indeterminate="true"
app:indicatorColor="#color/app_brand_primary"
app:trackColor="#color/color_divider"
app:trackCornerRadius="6dp"
app:trackThickness="12dp" />
p.s - it has a weird behaviour for toggling the indeterminate value programmatically. to do that you should
set visibility to invisible,
set indeterminate boolean,
then show the view again.
example :
progress.isVisible = false
progress.isIndeterminate = true
progress.isVisible = true
Issue :
https://github.com/material-components/material-components-android/issues/1921

Related

how to change android progress bar thickness

this should be a very easy to customize style...
i want a horizontal progress bar that is slithly thick (or that i can customize the thickness) and the color matches the apps color
if i do
<ProgressBar
android:id="#+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_below="#id/textLoading"
android:layout_centerHorizontal="true"
android:indeterminate="true"
/>
the progress bar is horizontal and matches app visual identity... but is too thin... the person need glases to see it
if i do
<ProgressBar
android:id="#+id/progressBar"
style="android:Widget.ProgressBar.Horizontal"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_below="#id/textLoading"
android:layout_centerHorizontal="true"
android:indeterminate="true"
/>
the progress bar is good thickness but the color is a stupid yellow that matches nothing in this plannet
how can i customize individual parameters???
there are many ways to achieve what you need:
1- use android:scaleY="8" in your XML file
or from code
mProgressBar.setScaleY(3f);
2- style="#android:style/Widget.ProgressBar.Horizontal"
this will make you have Horizontal progress bar, so you can inherit it in styles and edit it as follows:
<style name="CustomProgressBarHorizontal" parent="android:Widget.ProgressBar.Horizontal">
<item name="android:progressDrawable">#drawable/custom_progress_bar_horizontal</item>
<item name="android:minHeight">10dp</item>
<item name="android:maxHeight">20dp</item>
</style>
Here is an example for a progress bar:
<ProgressBar
android:id="#+id/progressBar"
style="#android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="20dp"
android:progressDrawable="#drawable/my_progressbar" />
and here is my_progressbar.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"
android:gravity="center_vertical|fill_horizontal">
<shape android:shape="rectangle">
<corners android:radius="10dp"/>
<size android:height="20dp"/>
<solid android:color="#color/blue"/>
</shape>
</item>
<item
android:id="#android:id/progress"
android:gravity="center_vertical|fill_horizontal">
<scale android:scaleWidth="100%">
<shape android:shape="rectangle">
<corners
android:radius="10dp"
/>
<size android:height="20dp"/>
<solid android:color="#color/yellow"/>
</shape>
</scale>
</item>
</layer-list>
Here is an example of how it looks:
You can use Android Material Progress Bar:
com.google.android.material.progressindicator.LinearProgressIndicator
XML example:
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="#+id/progressBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:progress="45"
app:indicatorColor="#color/blue_light"
app:trackColor="#FFFFFF"
app:trackCornerRadius="5dp"
app:trackThickness="10dp" />
Now you can use app:trackThickness to adjust the thickness of the progress bar
You can also check out Google's Material Design page regarding Material Progress Bar here: https://material.io/components/progress-indicators/android#using-progress-indicators
You can customize the style with:
<ProgressBar
android:id="#+id/progressBar"
android:indeterminate="true"
style="#style/CustomProgressBar"
with:
<style name="CustomProgressBar" parent="Widget.AppCompat.ProgressBar.Horizontal">
<item name="minHeight">32dip</item> <!-- default 16dp -->
<item name="maxHeight">32dip</item> <!-- default 16dp -->
</style>
If you want to customize the color use:
<ProgressBar
style="#style/CustomProgressBar"
android:indeterminate="true"
android:theme="#style/CustomProgressBarTheme"
/>
with:
<style name="CustomProgressBarTheme">
<item name="colorControlActivated">#color/....</item>
</style>

Custom Seek bar gets non highlight when touch outtside in its padding area

I have created custom seekbar to make it work according to my need. There are two questions related to it.
Before it let me show you my code for seekbar
In android xml
<com.abc.projectname.customlayout.CustomHorizontalSeekBar
android:id="#+id/progressBar1"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_centerVertical="true"
android:max="7650"
android:paddingLeft="30dp" // Padding given to show thumbnail properly
android:paddingRight="30dp"
android:clickable="false"
android:paddingTop="20dp"
android:tag="drawable/seek_bar_layout_two"
android:thumb="#drawable/dial" />
CustomHorizontalSeekBar Is a class which I have created to get the tag from seekbar and set progress drawable value as whatever tag have supplied to support multiple theme
seek_bar_layout_two xml file
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+android:id/background"
android:drawable="#drawable/deselect">
</item>
<item
android:id="#+android:id/progress"
android:top="20dp"
android:bottom="20dp"
android:drawable="#drawable/lt_grey_seek_bar">
</item>
<!-- android:drawable="#drawable/loadingbar"> -->
</layer-list>
Here deselect is and highlighted image which I want to show as background of seekbar permanently.
lt_grey_seek_bar xml
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="horizontal"
android:gravity="left" >
<shape android:shape="rectangle" >
<corners android:radius="5dp" />
<stroke
android:width="1dp"
android:color="#color/lt_grey_border" />
<gradient
android:endColor="#color/lt_grey_end"
android:startColor="#color/lt_grey_start" />
</shape>
</clip>
Questions
1) Can I give same background image for custom seekbar for enable and disable state? If yes than how? It is a special need from my client and it is not necessary to show disable state.
What I have tried:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_enabled="false"/>
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_pressed="true"/>
<item android:drawable="#drawable/seek_bar_layout_two xml" android:state_selected="true"/>
<item android:drawable="#drawable/seek_bar_layout_two xml"/>
</selector>
But Still no success.
2) As you can see in my seekbar implementation I have given padding to show proper thumbnail. But when I click outside the drawn state of seekbar where this padding is available seekbar automatically turns into non highlighted form. How should I stop it?
Seekbar and its touch area by which it gets non highlight
Non highlight seekbar look
I have been trying lots of ways to make it work successfully but unable to do so. Can anyone provide me a solution.
This is what I have done in my custom seekbar class
Rect bounds = getProgressDrawable().getBounds();
setProgressDrawable(getResources().getDrawable(idByTag));
getProgressDrawable().setBounds(bounds);

Creating secondary progress bar using multiple clips drawable

I am creating progress bar using imageview with layer list of clip drawable and it is working like a charm. Here is the code:
The xml of background drawable:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#android:id/background">
<bitmap android:src="#drawable/energy_backing" >
</bitmap>
</item>
<item android:id="#android:id/progress">
<clip
android:clipOrientation="horizontal"
android:drawable="#drawable/energy_full"
android:gravity="left" />
</item>
</layer-list>
The xml of progress bar:
<ImageView
android:id="#+id/pbEnergyBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:layout_centerHorizontal="true"
android:src="#drawable/progress_bar_energy2" />
And offcourse I can set the progress by calling imageview.setImageLevel(progress).
My question is , how can I add a secondary progress bar like the one in default ProgressBar ?
I thought of adding another clip drawable but then how can I call setLevel twice on two different clips? any guidance!
Thank you
You could just add another ImageView with the secondary layer list and lay it out exactly on top of the first ImageView...
EDIT: Actually, you might be able to use ProgressBar with your drawable.
add another layer to your list with <item android:id="#android:id/secondaryProgress">
in ProgressBar set android:progressDrawable="#drawable/progress_bar_energy2"
See if that works.

Remove text padding in Button view

I would like to remove the padding around text in Button view.
The first screenshot is the result I would achieve, and the second one is the state of the art.
Of course, I have defined a custom drawable to get the button appearance. But even if I set the padding attribute to 0dp the result does not change.
Any suggestion, please?
EDIT
Here is the xml code of the button
<Button
android:id="#+id/btnCancel"
style="#style/dark_header_button"
android:layout_width="wrap_content"
android:layout_marginLeft="10dp"
android:layout_height="wrap_content"
android:includeFontPadding="false"
android:padding="0dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="#android:string/cancel" />
Here is the style xml file:
<style name="dark_header_button">
<item name="android:background">#drawable/bkg_dark_header_button</item>
<item name="android:shadowDy">-1</item>
<item name="android:shadowColor">#000000</item>
<item name="android:shadowRadius">1</item>
<item name="android:textSize">14sp</item>
<item name="android:textColor">#ffffff</item>
</style>
and here is the drawable xml file:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape>
<corners android:radius="10dp" />
<gradient
android:angle="90"
android:endColor="#060606"
android:startColor="#707070"
android:type="linear" />
</shape>
</item>
<item>
<shape>
<corners android:radius="10dp" />
<gradient
android:angle="90"
android:endColor="#707070"
android:startColor="#060606"
android:type="linear" />
<stroke
android:width="0.5dp"
android:color="#2b2b2b" />
</shape>
</item>
</selector>
Its not actually padding but the theme is setting a minHeight and minWidth for button widgets. You can completely remove this effect without changing your theme by setting the following on your button in the xml:
android:minHeight="0dp"
android:minWidth="0dp"
It thus also implies that you can play around with different settings for different effects, 0dp is merely an example to completely remove this effect.
you can try using android:includeFontPadding. set it to false. also set the padding to 0.
Button text doesn't need padding, it is by default in center of the button.
I think you are using the android:theme="#android:style/Theme.Black.NoTitleBar" in the manifest file, please remove it and use native app Theme and try it.

Seekbar or progress bar with multiple colors

I want to create a bar like this initially when progress is zero it will be a fade in color but and as progress goes on it will become bright on that part(This is best I can explain) main thing is i want bar to show all colors at the same time.
Clip your "on" drawable:
over your "off" drawable:
by using res/drawable/custom_progress_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Background -->
<item
android:id="#android:id/background"
android:drawable="#drawable/custom_progress_bar_off"/>
<!-- Secondary progress - this is optional -->
<item android:id="#android:id/secondaryProgress">
<clip android:drawable="#drawable/custom_progress_bar_secondary" />
</item>
<!-- Progress -->
<item android:id="#android:id/progress">
<clip android:drawable="#drawable/custom_progress_bar_on" />
</item>
</layer-list>
From an Activity, use
Drawable progressDrawable = ResourcesCompat.getDrawable(getResources(), R.drawable.custom_progress_drawable, getTheme());
myProgressBar.setProgressDrawable(progressDrawable);
or in xml, use
android:progressDrawable="#drawable/custom_progress_drawable"
And here's the result when using android:max="10" in xml:
It's a little bit off, but you could use setMax() with something more like 10000 and do some offsetting calculations when calling setProgress() to make it cleaner.
Finally! I went on a mission to figure this out for you, so if this suffices, feel free to give me that bounty, haha.
Try using this in your layout:
<View android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight=".20"/>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:orientation="horizontal"
android:gravity="center"
android:layout_weight="0.62">
<View android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight=".03"/>
<ProgressBar style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight="0.94"
android:progressDrawable="#drawable/progressmask"
android:progress="0"
android:max="10"
android:rotation="180"/>
<View android:layout_width="0dip"
android:layout_height="fill_parent"
android:layout_weight=".03"/>
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight=".18"/>
</LinearLayout>
which references this drawable (progressmask.xml):
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#android:id/background">
<shape>
<corners android:radius="50dip" />
<gradient android:startColor="#00000000" android:endColor="#00000000" android:angle="270" />
<stroke android:width="1dp" android:color="#00000000" />
</shape>
</item>
<item android:id="#android:id/progress">
<clip>
<shape>
<corners android:radius="50dip" />
<gradient android:startColor="#aa000000" android:endColor="#aa000000"
android:angle="270" />
<stroke android:width="1dp" android:color="#00000000" />
</shape>
</clip>
</item>
</layer-list>
and this image (colorprogress.png)
What it does is set the image as the background of a linearlayout, which contains a progressbar. The progressbar adds a semi-transparent black mask to the image to make it appear that the lights are off.
NOTE: In order to get this affect, I had to monkey with the progress bar (i.e. flip it, and set it to only 10 intervals. You will have to do some math to get the progress to line up with the image. i.e. setprogress((100-trueprogress)/10). Sorry I did not do this part for you.
This is what it will look like at progress 50% (the small x's and triangles will disappear on the device)
I hope this answers your question!
Like already suggested i think you should go for an layer-list and set multiple drawables then.
Main problem on this is that i need to be resizeable. An fixed size solution would be quite easy to implement.
You can't actually set the progress bars to different colors. You can however use only the on drawable and get the effect that you want. You could just apply a layer mask. What I mean is add a Relative layout which is initially say dark grey throughout i.e the gradient has only ONE color which is dark gray. Now, use code to set the gradient color on the left programmatically. Obviously the color on the left is going to be transparent. Learn more about Linear Gradients. That's about it. You just need to calculate the position from where the right gradient starts, rather where the left gradient(transparent)ends.
This method is slightly flawed and may not work on ALL devices.
The flawless method would be to create multiple .9png images and set the drawable of the progress dialog programmatically every time.

Categories

Resources