Is it possible to create an Android shape object with stroke on only certain sides?
Eg I have:
<stroke
android:width="3dip"
android:color="#000000"
android:dashWidth="10dip"
android:dashGap="6dip" />
Which is similar to this CSS:
border: 3px dashed black;
How can I set the stroke on just one side? This is how I would do it in CSS:
border-left: 3px dashed black;
How do you do this in Android XML?
Sometimes you want an outline around your shape and to do that you can use the stroke tag. You can specify the width and color of the outline using android:width and android:color.
Layer list. A LayerDrawable is a drawable object that manages an array of other drawables. Each drawable in the list is drawn in the order of the list—the last drawable in the list is drawn on top. Each drawable is represented by an <item> element inside a single <layer-list> element.
canClip() method. To clip a view to the shape of a drawable, set the drawable as the background of the view (as shown above) and call the View. setClipToOutline() method.
I achieved a good solution with this one:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item android:top="-1dp" android:right="-1dp" android:left="-1dp">
<shape>
<solid android:color="@android:color/transparent" />
<stroke android:width="1dp" android:color="#ffffff" />
</shape>
</item>
</layer-list>
This works well in case you need a transparent background but still an open stroke color (In my case I only needed a bottom line). If you need a background color you can add a solid shape color as in Maragues answer.
EDIT 1
Sometimes, for High Density devices, using low dip values may end in very thin or invisible strokes or distances. This may happen to you also when setting ListView dividers.
The simplest workaround is to use a distance of 1px instead of 1dp. This will make the line always visible at all densities. The best solution would be to create dimension resources for each density, to get the best size for each device.
Edit 2
Fun, but I tried to use this 6 years later and I can't get a good result on Lollipop devices.
Probably the current solution is to use 9-patch. Android should have made an easy solution for this problem after all this time.
I know this question was posted long ago, so the answer will not be used by the person who posted this question, but it may still help others.
<?xml version="1.0" encoding="UTF-8"?>
<!-- inset is used to remove border from top, it can remove border from any other side-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="-2dp"
>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/rectangle">
<stroke android:width="1dp" android:color="#b7b7b7" />
<corners android:bottomRightRadius="5dp" android:bottomLeftRadius="5dp"/>
<solid android:color="#454444"/>
</shape>
</inset>
Use the inset
tag and give a negative value for the side border you want to remove.
The possible values are:
android:insetTop="-1dp"
android:insetBottom="-1dp"
android:insetLeft="-1dp"
android:insetRight="-1dp"
I solved this by using a list-layer, combining two shapes, one of which with height 1dp placed at the bottom
optionscreen_bottomrectangle.xml:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- This is the line -->
<item>
<shape>
<solid android:color="#535353" />
</shape>
</item>
<!-- This is the main color -->
<item android:bottom="1dp">
<shape>
<solid android:color="#252525" />
</shape>
</item>
</layer-list>
Then, in the layout/main.xml file
<TextView
android:id="@+id/bottom_rectangle"
android:background="@drawable/optionscreen_bottomrectangle"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_below="@id/table_options"
android:layout_above="@id/exit_bar"/>
Which fills the gap between table_options and exit_bar with a background and just before exit_bar prints a 1dp line. This did the trick for me, I hope it helps someone else.
Answer edited to place layers in the correct order. Thx Alex!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With