ZoolWay
ZoolWay

Reputation: 5505

Shape drawable as background, a line at the bottom

I am using a drawable as a background of a TextView just to have a divider line below the text. A achivied it with this drawable-xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
        <shape 
        android:shape="rectangle">
            <solid android:color="#FFDDDDDD" />
            <gradient 
                android:angle="0"
                android:startColor="#FFAAAAAA"
                android:endColor="#FFEEEEEE"
                />
        </shape>
    </item>

    <item android:bottom="2dp">
        <shape 
        android:shape="rectangle">
            <solid android:color="#FF000000" />
        </shape>
    </item>

</layer-list>

But this method draws a colored rectangle above a black rectangle. I would like to have just the line at the bottom of the shape with no black rectangle because black is not transparent. How could I achieve that?

Upvotes: 77

Views: 95117

Answers (8)

This solution worked for most of the cases that I needed something like that.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent" /> <!--background color of box-->
        </shape>
    </item>

    <item
        android:height="2dp"
        android:gravity="bottom">
        <shape>
            <solid android:color="#000000" />
        </shape>
    </item>
</layer-list>

Upvotes: 3

Dustin
Dustin

Reputation: 2154

This is a slightly lighter variant of the above.

/drawable/rect_highlight.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <stroke android:width="1px" android:color="@color/colorHighlight"/>
</shape>

/drawable/underline.xml

<inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="-1px" android:insetRight="-1px" android:insetTop="-1px" android:drawable="@drawable/rect_highlight"/>

Usage:

<TextView ... android:background="@drawable/underline"/>

It's not mine, somebody smarter than I came up with it. If I was smarter, I would have asked who. :)

Upvotes: 2

Freddie
Freddie

Reputation: 210

A simple solution is extending a TextView, then override the onDraw.

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint paint = new Paint();
    paint.setColor(ContextCompat.getColor(getContext(),R.color.colorTextUnderLine));
    paint.setStrokeWidth(10);
    canvas.drawLine(0.0f,canvas.getHeight(),canvas.getWidth(),canvas.getHeight(),
            paint);
}

Upvotes: -1

Go Rose-Hulman
Go Rose-Hulman

Reputation: 2707

This is how I got a line at the bottom for mine. Draw a stroke but then shift the item up and to the sides to get the top and sides to not show the stroke:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="-8dp" android:left="-8dp" android:right="-8dp">
        <shape> 
            <solid android:color="#2b7996"/>
            <stroke android:color="#33b5e5" android:width="6dp"/>
        </shape>
    </item>
</layer-list>

Upvotes: 224

Tara
Tara

Reputation: 2648

With this solution where ever you require different line you can. My requirement was underline only. Even you can give different colors to the layout. You can see in below picture, white line enter image description here

    <?xml version="1.0" encoding="UTF-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item android:top="-5dp" android:left="-5dp" android:right="-5dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke android:color="@color/white" android:width="5dp"/>
        </shape>
    </item>

    <item android:top="-5dp" android:bottom="-5dp" android:right="-5dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke android:color="@color/colorPrimaryDark" android:width="5dp"/>
        </shape>
    </item>

    <item android:bottom="-5dp" android:left="-5dp" android:right="-5dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke android:color="@color/colorPrimaryDark" android:width="5dp"/>
        </shape>
    </item>

    <item android:top="-5dp" android:left="-5dp" android:bottom="-5dp">
        <shape>
            <solid android:color="@android:color/transparent"/>
            <stroke android:color="@color/colorPrimaryDark" android:width="5dp"/>
        </shape>
    </item>

    <item android:bottom="2dp" android:left="5dp" android:right="5dp" android:top="5dp">
        <shape>
            <solid android:color="@color/colorPrimary"/>

            <corners android:bottomRightRadius="0dp"
                android:bottomLeftRadius="0dp"
                android:topLeftRadius="0dp"
                android:topRightRadius="0dp" />
        </shape>
    </item>
</layer-list>

Upvotes: 3

Lanitka
Lanitka

Reputation: 932

Usually for similar tasks - I created layer-list drawable like this one:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <solid android:color="@color/underlineColor"/>
    </shape>
</item>
<item android:bottom="3dp">
    <shape android:shape="rectangle">
        <solid android:color="@color/buttonColor"/>
    </shape>
</item>

The idea is that first you draw the rectangle with underlineColor and then on top of this one you draw another rectangle with the actual buttonColor but applying bottomPadding. It always works.

But when I needed to have buttonColor to be transparent I couldn't use the above drawable. I found one more solution

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
    <shape android:shape="rectangle">
        <solid android:color="@android:color/transparent"/>
    </shape>
</item>

<item android:drawable="@drawable/white_box" android:gravity="bottom" android:height="2dp"/>
</layer-list>

(as you can see here the mainButtonColor is transparent and white_box is just a simple rectangle drawable with white Solid)

Upvotes: 7

Dmitry Velychko
Dmitry Velychko

Reputation: 1535

I think it's better solution:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:gravity="bottom">
        <shape>
            <size android:height="1dp" />
            <solid android:color="#000000" />
        </shape>
    </item>
</layer-list>

Upvotes: 58

dmon
dmon

Reputation: 30168

In general, I try to mess as little as possible with backgrounds unless absolutely necessary, since doing so overrides the default background colors that have states for focused, pressed, etc. I suggest just using an additional view (in a vertical LinearLayout) that is as thick as you need it to be. For example:

 <View 
       android:background="#FF000000" 
       android:layout_height="2dp" 
       android:layout_width="fill_parent"/>

Upvotes: 32

Related Questions