Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: SeekBar with custom drawable

I have SeekBar with custom drawable. Progress element is not rendered from left side exactly but it is moved to right. How can I avoid this?

enter image description here

<SeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@android:id/summary"
    android:background="@null"

    android:progressDrawable="@drawable/seekbar"
    android:thumb="@drawable/seekbar_thumb"/>

seekbar.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:drawable="@drawable/seekbar_background"/>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress" />
    </item>

</layer-list>

seekbar_background.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">

    <stroke android:width="2dp" android:color="@color/colorNeutral" />

</shape>

seekbar_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="line">

    <stroke
        android:width="4dp"
        android:color="@color/colorAccentDark" />
</shape>

EDIT:

As mentioned in comments if there will be both widths same problem disappear. But I need make it with two different widths through drawable is it possible? Maybe with different shapes not just lines?

like image 599
Michal Avatar asked Jan 21 '16 19:01

Michal


4 Answers

I can not explain why this is an issue when drawing strokes, I think it has something to do with the strokes width, but I did not yet find the source to verify.

Fixing the Overlay

To remove the issue at hand, you can just set an inset on your left side. A value of 1dp or 2dp both work and the seekbar will be drawn properly.

Note: Using this approach there should be no risk that the background could be too short and not visible with low progress values, since the thumb would overlay and hide it in any case.

<?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/seekbar_background"
        android:left="2dp"><!-- or 1dp -->
    </item>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress"/>
    </item>
</layer-list>
like image 87
David Medenjak Avatar answered Oct 10 '22 20:10

David Medenjak


Observation

When you create a line using shape drawable it leaves the left and right padding (from the view in which this drawable is being used.)equal to the half of its stroke width.

Workaround

You need to wrap your progress_background with an inset drawable and then set it as progress background. The inset can be like the following-

inset_seekbar_background.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/seekbar_progress"
    android:insetLeft="2dp"
    android:insetRight="2dp" />

and your final seekbar.xml will be like-

<?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/inset_seekbar_background"/>
    <item android:id="@android:id/progress">
        <clip android:drawable="@drawable/seekbar_progress" />
    </item>

</layer-list>

Alternates

1.You can use an 9 path image for line as it is done in the default material design-

<?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/abc_scrubber_primary_mtrl_alpha" />
    <item android:id="@android:id/secondaryProgress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="false">
                    <color android:color="@android:color/transparent" />
                </item>
                <item android:drawable="@drawable/abc_scrubber_primary_mtrl_alpha" />
            </selector>
        </scale>
    </item>
    <item android:id="@android:id/progress">
        <scale android:scaleWidth="100%">
            <selector>
                <item android:state_enabled="true">
                    <color android:color="@android:color/transparent" />
                </item>
                <item android:drawable="@drawable/abc_scrubber_primary_mtrl_alpha" />
            </selector>
        </scale>
    </item>
</layer-list><!-- From: file:/usr/local/google/buildbot/src/googleplex-android/mnc-supportlib-release/frameworks/support/v7/appcompat/res/drawable/abc_seekbar_track_material.xml -->

enter image description here enter image description here enter image description here enter image description here

2.You can set the theme to your view with different color in android style as-

<style name="AppTheme.SeekBar">
        <item name="colorPrimary">@color/colorAccent</item>
        <item name="colorPrimaryDark">@color/colorPrimary</item>
        <item name="colorAccent">@color/colorPrimaryDark</item>
</style>

Here I have used all there options for Seekbars-

            <SeekBar 
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:theme="@style/AppTheme.SeekBar" />

            <SeekBar
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <SeekBar
                android:layerType="software"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:progressDrawable="@drawable/seekbar" />

And here is the output- enter image description here

like image 22
Sanjeet A Avatar answered Oct 10 '22 20:10

Sanjeet A


As it appear the issue in progress I think they both should be the same width

but you in progress make width = 4 android:width="4dp"

and seekbar width = 2 android:width="2dp"

just match them to be 2 or 4 dont use different values

like image 3
Mina Fawzy Avatar answered Oct 10 '22 18:10

Mina Fawzy


Try using a .9.png drawable of width 4dp (converted to px) .

Keep 1 dp at top and bottom transparent.

And add colour to the center 2 dp of your choice for the background.

This way both background and progress will be of same width but the background will look thinner than progress bar.

like image 3
Arnab Jain Avatar answered Oct 10 '22 19:10

Arnab Jain