make custom xml shape android - android

I need to make custom shape like below:
in order to do that I've wrote below xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
>
<item android:id="#+id/ring1">
<shape
android:innerRadiusRatio=""
android:shape="ring"
android:tint="#color/white"
android:useLevel="false"></shape>
</item>
<item>
<shape
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:innerRadius="0dp"
android:shape="ring"
android:thickness="140dp"
android:useLevel="false">
<gradient
android:centerColor="#00F913"
android:endColor="#006A10"
android:startColor="#006A10" />
</shape>
</item>
</layer-list>
which it's result is:
And there is 3 problems:
1st: when I give it to any views background the outer white line
wouldn't appear
2nd: the shape is not a ring when i give it to views background
3rd: the original view has a color at center and it has other color
around but with gradient I can add color to start, center, end and
in the middle the middle gradient is extends to borders

1st: when I give it to any views background the outer white line wouldn't appear
You can use oval shape instead of using ring for the white part., and add padding as much you need the radius of the outer white part as modified below
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid android:color="#color/white" />
<padding
android:bottom="7dp"
android:left="7dp"
android:right="7dp"
android:top="7dp" />
</shape>
</item>
<item>
<shape android:shape="oval">
<size
android:width="36dp"
android:height="36dp" />
<gradient
android:centerColor="#00F913"
android:endColor="#006A10"
android:startColor="#006A10" />
</shape>
</item>
</layer-list>
2nd: the shape is not a ring when i give it to views background
You can use ShapeableImageView
First: add below dependency in gradle module level
implementation 'com.google.android.material:material:1.3.0-alpha04'
Second: create below style in style.xml
<style name="circled">
<item name="cornerSize">50%</item>
</style>
Third: apply the style to a ShapeableImageView using app:shapeAppearanceOverlay attribute
3rd: the original view has a color at center and it has other color around but with gradient I can add color to start, center, end and in the middle the middle gradient is extends to borders
This should be solved by using ShapeableImageView, please check below result after running the app
Sample test
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:background="#color/colorAccent"
android:layout_height="match_parent">
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="100dp"
android:layout_height="100dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="#style/circled"
app:srcCompat="#drawable/some_circle" />
</androidx.constraintlayout.widget.ConstraintLayout>

Related

android:How to make triangular layout

I want to make custom Info window for google map
I can make it but I am not able to make triangle bellow layout.
I can add image there but layout have shadow on outer line.
Anyone suggest me what to do.
how to make portion inside red area. as you can see outer layout have shadow.
You can use the Material Component Library to create custom shapes.
The library provides the TriangleEdgeTreatment which creates a triangle treatment of the given size, which faces inward or outward relative to the shape.
You can use something like:
TriangleEdgeTreatment triangleEdgeTreatment = new TriangleEdgeTreatment(radius,false);
LinearLayout linearLayout= findViewById(R.id.xxxx);
ShapeAppearanceModel shapeAppearanceModel = new ShapeAppearanceModel()
.toBuilder()
.setBottomEdge(triangleEdgeTreatment)
.build();
MaterialShapeDrawable shapeDrawable = new MaterialShapeDrawable(shapeAppearanceModel);
ViewCompat.setBackground(linearLayout,shapeDrawable);
Also for edge treatments the parent view must disable clipping of children by
setting android:clipChildren="false" in xml.clipToPadding may also need to be false if there is any padding on the parent that could intersect the shadow.
This can be achieved using MaterialCardView and Shape theming.
Dependency: (Use the latest stable version)
def materialVersion = '1.3.0'
implementation "com.google.android.material:material:$materialVersion"
Layout:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.card.MaterialCardView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardBackgroundColor="#color/backgroundWhite"
app:cardElevation="4dp"
app:cardCornerRadius="8dp">
//Content layout here
</com.google.android.material.card.MaterialCardView>
<com.google.android.material.card.MaterialCardView
style="#style/PointerCardViewStyle"
android:layout_width="20dp"
android:layout_height="10dp"
app:cardBackgroundColor="#color/whiteColor"
android:layout_gravity="center"
app:cardElevation="4dp" />
</LinearLayout>
Style:
<style name="PointerCardViewStyle" parent="Widget.MaterialComponents.CardView">
<item name="shapeAppearanceOverlay">#style/ShapeAppearanceOverlayPointerCardView</item>
</style>
<style name="ShapeAppearanceOverlayPointerCardView" parent="#style/Widget.MaterialComponents.CardView">
<item name="cornerFamily">cut</item>
<item name="cornerSizeTopRight">0dp</item>
<item name="cornerSizeTopLeft">0dp</item>
<item name="cornerSizeBottomRight">10dp</item>
<item name="cornerSizeBottomLeft">10dp</item>
</style>
Result:
You can create this custom shape using <layer-list>. Below is a working example. Put custom_triangular_shape.xml into your res/drawable folder.
custom_triangular_shape.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Transparent Rectangle -->
<item>
<shape android:shape="rectangle">
<size
android:width="300dp"
android:height="80dp" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
<!-- Colored Rectangle -->
<item
android:bottom="20dp">
<shape android:shape="rectangle">
<corners
android:radius="4dp">
</corners>
<size
android:width="300dp"
android:height="80dp" />
<solid android:color="#FFFFFF" />
</shape>
</item>
<!-- Bottom Triangle -->
<item
android:left="90dp"
android:right="110dp"
android:top="0dp"
android:bottom="30dp">
<rotate android:fromDegrees="45">
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" />
</shape>
</rotate>
</item>
</layer-list>
USE:
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_triangular_shape">
</LinearLayout>
OUTPUT:
Hope this will help~
Try this:
For triangle :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:fromDegrees="45"
android:pivotX="-40%"
android:pivotY="87%"
android:toDegrees="45">
<shape android:shape="rectangle">
<stroke
android:width="10dp"
android:color="#android:color/transparent" />
<solid android:color="#000000" />
</shape>
</rotate>
</item>
</layer-list>
For rectangle:
<?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="#B2E3FA" />
</shape>
</item>
</layer-list>
Use both xml in the Layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/rlv1"
android:layout_width="150dp"
android:layout_height="50dp"
android:background="#drawable/rectringle" />
<RelativeLayout
android:id="#+id/rlv2"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_below="#+id/rlv1"
android:layout_marginLeft="30dp"
android:background="#drawable/tringle"
android:rotation="180" />
</LinearLayout>
You can make use of layer-list. Create a triangular shape at the bottom, then create a rectangular shape as next layer and give bottom margin that matches your triangle's height.
here is a sample to make triangle shape. https://stackoverflow.com/a/18421795/1987045
You can use a 9patch as background for your custom layout.
Using PopUpWindow you can achieve your goal. Here is a good link to start with.

How to add shadow using a drawable behind solid color shape in xml?

I have a .png image which is a circular shape and is just a shadow. What I have is an ImageButton which has an image for its android:src property. For its background I can have an xml file in drawable file. What I want now is to have the shadow image which is a png to go behind another solid shape -> android:shape="oval".
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/shadowimg" />
<item>
<shape android:shape="oval">
<solid
android:color="#d63a33"/>
<size
android:width="70dp"
android:height="70dp"/>
</shape>
</item>
</layer-list>
As you see in the code I am adding an item with the shadow image with the android:drawable property. However this does not let the shadow show. It simply shows the red circle shape. But I want the shadow image behind the solid red circle shape. From my tiny knowledge of layer-list the top item goes in the back and the one on bottom comes first.
UPDATE: After moving the image shadow to bottom I got the effect however the size of the solid red circle shape is too big and changing the size doesn't change the size.
UPDATED Code:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid
android:color="#d63a33"/>
<size
android:width="5dp"
android:height="5dp"/>
</shape>
</item>
<item android:drawable="#drawable/shadowimg" />
</layer-list>
**** UPDATE 2: ****
I noticed when I remove <item android:drawable="#drawable/shadowimg" /> I can change size of solid circle shape but when I add this it defaults to a bigger size.
This is what happens:
Here's the shadow image if anyone needs:
I think this should be your solution:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="oval" >
<solid android:color="#d63a33" />
<size
android:height="5dp"
android:width="5dp" />
</shape>
</item>
<item>
<bitmap android:src="#drawable/shadowimg" />
</item>
<item>
<shape android:shape="oval" >
<solid android:color="#00000000" />
<size
android:height="5dp"
android:width="5dp" />
</shape>
</item>
</layer-list>
I added another transparent layer with the desired size.
Actually the issue is in the shadow you are using, the shadow itself leaves some padding. so what we can do is, leave some space in the solid color we are filling in the first item by using stroke.
use this code:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="oval" >
<solid android:color="#d63a33" />
<stroke
android:width="7dp"
android:color="#00000000" />
</shape>
</item>
<item android:drawable="#drawable/shadowimg"/>
</layer-list>
and then use with 30dp of height and 30dp of width, like
<TextView
android:id="#+id/titleText"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_centerVertical="true"
android:layout_marginLeft="16dp"
android:background="#drawable/circle_white"
android:fontFamily="sans-serif-thin"
android:gravity="center"
android:text="Hi"
android:textColor="#FF000000"
android:textSize="16sp" />
if you want to increase the height and width of the view, simply increase the width of the stroke too..

Custom View with Layer-List background drawable renders black screen

I'm trying to build a custom android view and apply a background drawable that is a layer-list.
The layer-list has two items:
A background color (white)
A simple shape drawable that is a stroked rectangle with rounded-corners
here's the drawable xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#android:color/white"/>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="1dp" />
<stroke
android:width="2dp"
android:color="#color/background_green" />
</shape>
</item>
</layer-list>
The custom view is a class derving from Android.view.View that currently has NO functionality except the required measuring overloads.
I'm applying the background in the view definition in an activity layout:
<view
android:layout_width="match_parent"
android:layout_height="300dp"
class="com.example.widget.TestView"
android:id="#+id/view2"
android:layout_gravity="center_horizontal"
android:background="#drawable/rect_sig_cap"
android:layout_margin="20dp" />
What I expect to see is a view with a white background and a green border. What I actually see when I deploy the project is a view with a black background and a green border.
Interestingly it appears correctly in the designer preview in Android Studio. It's only when I deploy it to a device that it renders black.
Am I missing something obvious here?
For those interested, I found the solution.
I had defined the shape drawable as including only a stroke definition. Without any other inputs, this causes the fill color to be inferred as black.
In the end, a Layer-List drawable is not required at all. Instead, add a solid fill definition to the shape layer with color Transparent and it works just fine.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="#dimen/corner_radius" />
<stroke android:width="1dp"
android:color="#color/background_green" />
<solid android:color="#android:color/transparent" />
</shape>
Try this one.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<color android:color="#color/white" />
</item>
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="1dp" />
<stroke
android:width="2dp"
android:color="#color/background_green" />
</shape>
</item>
</layer-list>

Show only left and right borders of a rectangle [duplicate]

I have a TextView and I'd like to add a black border along its top and bottom borders. I tried adding android:drawableTop and android:drawableBottom to the TextView, but that only caused the entire view to become black.
<TextView
android:background="#android:color/green"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableTop="#android:color/black"
android:drawableBottom="#android:color/black"
android:text="la la la" />
Is there a way to easily add a top and bottom border to a View (in particular, a TextView) in Android?
In android 2.2 you could do the following.
Create an xml drawable such as /res/drawable/textlines.xml and assign this as a TextView's background property.
<TextView
android:text="My text with lines above and below"
android:background="#drawable/textlines"
/>
/res/drawable/textlines.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FF000000" />
<solid android:color="#FFDDDDDD" />
</shape>
</item>
<item android:top="1dp" android:bottom="1dp">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FFDDDDDD" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
The down side to this is that you have to specify an opaque background colour, as transparencies won't work. (At least i thought they did but i was mistaken). In the above example you can see that the solid colour of the first shape #FFdddddd is copied in the 2nd shapes stroke colour.
I've used a trick so that the border is displayed outside the container. With this trick only a line is drawn so the background will be shown of the underlying view.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="1dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle" >
<stroke
android:width="1dp"
android:color="#FF000000" />
<solid android:color="#00FFFFFF" />
<padding android:left="10dp"
android:right="10dp"
android:top="10dp"
android:bottom="10dp" />
</shape>
</item>
</layer-list>
To add a 1dp white border at the bottom only and to have a transparent background you can use the following which is simpler than most answers here.
For the TextView or other view add:
android:background="#drawable/borderbottom"
And in the drawable directory add the following XML, called borderbottom.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-2dp" android:left="-2dp" android:right="-2dp">
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#ffffffff" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
If you want a border at the top, change the android:top="-2dp" to android:bottom="-2dp"
The colour does not need to be white and the background does not need to be transparent either.
The solid element may not be required. This will depend on your design (thanks V. Kalyuzhnyu).
Basically, this XML will create a border using the rectangle shape, but then pushes the top, right and left sides beyond the render area for the shape. This leaves just the bottom border visible.
Option 1: Shape Drawable
This is the simplest option if you want a border around a layout or view in which you can set the background. Create an XML file in the drawable folder that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#8fff93" />
<stroke
android:width="1px"
android:color="#000" />
</shape>
You can remove the solid if you don't want a fill. The set background="#drawable/your_shape_drawable" on your layout/view.
Option 2: Background View
Here's a little trick I've used in a RelativeLayout. Basically you have a black square under the view you want to give a border, and then give that view some padding (not margin!) so the black square shows through at the edges.
Obviously this only works properly if the view doesn't have any transparent areas. If it does I would recommend you write a custom BorderView which only draws the border - it should only be a few dozen lines of code.
<View
android:id="#+id/border"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/image"
android:layout_alignLeft="#+id/image"
android:layout_alignRight="#+id/image"
android:layout_alignTop="#+id/main_image"
android:background="#000" />
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_...
android:padding="1px"
android:src="#drawable/..." />
If you're wondering, it does work with adjustViewBounds=true. However, it doesn't work if you want to have a background in an entire RelativeLayout, because there is a bug that stops you filling a RelativeLayout with a View. In that case I'd recommend the Shape drawable.
Option 3: 9-patch
A final option is to use a 9-patch drawable like this one:
You can use it on any view where you can set android:background="#drawable/...". And yes it does need to be 6x6 - I tried 5x5 and it didn't work.
The disadvantage of this method is you can't change the colours very easily, but if you want fancy borders (e.g. only a border at the top and bottom, as in this question) then you may not be able to do them with the Shape drawable, which isn't very powerful.
Option 4: Extra views
I forgot to mention this really simple option if you only want borders above and below your view. You can put your view in a vertical LinearLayout (if it isn't already) and then add empty Views above and below it like this:
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1px"/>
The currently accepted answer doesn't work. It creates thin vertical borders on the left and right sides of the view as a result of anti-aliasing.
This version works perfectly. It also allows you to set the border widths independently, and you can also add borders on the left / right sides if you want. The only drawback is that it does NOT support transparency.
Create an xml drawable named /res/drawable/top_bottom_borders.xml with the code below and assign it as a TextView's background property.
<?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="#DDDD00" /> <!-- border color -->
</shape>
</item>
<item
android:bottom="1dp"
android:top="1dp"> <!-- adjust borders width here -->
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" /> <!-- background color -->
</shape>
</item>
</layer-list>
Tested on Android KitKat through Marshmallow
So I wanted to do something slightly different: a border on the bottom ONLY, to simulate a ListView divider. I modified Piet Delport's answer and got this:
<?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="#color/background_trans_light" />
</shape>
</item>
<!-- this mess is what we have to do to get a bottom border only. -->
<item android:top="-2dp"
android:left="-2dp"
android:right="-2dp"
android:bottom="1px">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/background_trans_mid" />
<solid android:color="#null" />
</shape>
</item>
</layer-list>
Note using px instead of dp to get exactly 1 pixel divider (some phone DPIs will make a 1dp line disappear).
Add file to res/drawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="-2dp" android:right="-2dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#000000" />
</shape>
</item>
</layer-list>
Add link on this file to background property
Just as #Nic Hubbard said, there is a very easy way to add a border line.
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#000000" >
</View>
You can change the height and background color to whatever you want.
You can also wrap the view in a FrameLayout, then set the frame's background color and padding to what you want; however, the textview, by default has a 'transparent' background, so you'd need to change the textview's background color too.
My answers is based on #Emile version but I use transparent color instead of solid.
This example will draw a 2dp bottom border.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#50C0E9" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
<item android:bottom="2dp" >
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#color/bgcolor" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
</layer-list>
#color/bgcolor is the color of the background on wich you draw your view with border.
If you want to change the position of the border change the offset with one of:
android:bottom="2dp"
android:top="2dp"
android:right="2dp"
android:left="2dp"
or combine them to have 2 or more borders:
android:bottom="2dp" android:top="2dp"
You can do this by this code snippet -
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--Minus (-) how much dp you gave in the stroke width from left right-->
<item android:left="-10dp" android:right="-10dp">
<shape
android:shape="rectangle">
<stroke android:width="10dp" android:color="#android:color/holo_red_dark" />
<!--This is the main background -->
<solid android:color="#FFDDDDDD" />
</shape>
</item>
</layer-list>
Preview -
Why not just create a 1dp high view with a background color? Then it can be easily placed where you want.
To change this:
<TextView
android:text="My text"
android:background="#drawable/top_bottom_border"/>
I prefer this approach in "drawable/top_bottom_border.xml":
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="270"
android:startColor="#000"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="90"
android:startColor="#000"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />
</shape>
</item>
</layer-list>
This only makes the borders, not a rectangle that will appear if your background has a color.
Simplest way to add borders to inset the borders using InsetDrawable,following will show top border only :
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="-2dp"
android:insetLeft="-2dp"
android:insetRight="-2dp">
<shape android:shape="rectangle">
<solid android:color="#color/light_gray" />
<stroke
android:width=".5dp"
android:color="#color/dark_gray" />
</shape>
</inset>
Just to add my solution to the list..
I wanted a semi transparent bottom border that extends past the original shape (So the semi-transparent border was outside the parent rectangle).
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#33000000" /> <!-- Border colour -->
</shape>
</item>
<item android:bottom="2dp" >
<shape android:shape="rectangle" >
<solid android:color="#164586" />
</shape>
</item>
</layer-list>
Which gives me;
First make a xml file with contents shown below and name it border.xml and place it inside the layout folder inside the res directory
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="1dp" android:color="#0000" />
<padding android:left="0dp" android:top="1dp" android:right="0dp"
android:bottom="1dp" />
</shape>
After that inside the code use
TextView tv = (TextView)findElementById(R.id.yourTextView);
tv.setBackgroundResource(R.layout.border);
This will make a black line on top and bottom of the TextView.
Simply add Views at the top and bottom of the View
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/your_color"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="#+id/textView"
app:layout_constraintStart_toStartOf="#+id/textView" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="Testing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/your_color"
app:layout_constraintEnd_toEndOf="#+id/textView"
app:layout_constraintStart_toStartOf="#+id/textView"
app:layout_constraintTop_toBottomOf="#+id/textView" />
</android.support.constraint.ConstraintLayout>
Write down below code
<View
android:layout_width="wrap_content"
android:layout_height="2dip"
android:layout_below="#+id/topics_text"
android:layout_marginTop="7dp"
android:layout_margin="10dp"
android:background="#ffffff" />
Try wrapping the image with a linearlayout, and set it's background to the border color you want around the text. Then set the padding on the textview to be the thickness you want for your border.
You can also use a 9-path to do your job. Create it so that colored pixel do not multiply in height but only the transparent pixel.
Based on accepted answer of Pi Delport and Emile, I made it a little simpler
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item> <!--divider TOP and BOTTOM-->
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/divider" />
</shape>
</item>
<!--background surface-->
<item
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/background" />
</shape>
</item>
// Just simply add border around the image view or view
<ImageView
android:id="#+id/imageView2"
android:layout_width="90dp"
android:layout_height="70dp"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_toLeftOf="#+id/imageView1"
android:background="#android:color/white"
android:padding="5dip" />
// After that dynamically put color into your view or image view object
objView.setBackgroundColor(Color.GREEN);
//VinodJ/Abhishek
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/light_grey1" />
<stroke
android:width="1dip"
android:color="#color/light_grey1" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#72cdf4"
android:text=" aa" />
Just Add this TextView below the text where you want to add the border
Just to enforce #phreakhead ´s and user1051892 ´s answers, <item android:bottom|android:left|android:right|android:top> if negative, must to be greater than <stroke android:width>. If not, item´s painting will be mixed with stroke´s painting and you may think these values are not working.

Is there an easy way to add a border to the top and bottom of an Android View?

I have a TextView and I'd like to add a black border along its top and bottom borders. I tried adding android:drawableTop and android:drawableBottom to the TextView, but that only caused the entire view to become black.
<TextView
android:background="#android:color/green"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawableTop="#android:color/black"
android:drawableBottom="#android:color/black"
android:text="la la la" />
Is there a way to easily add a top and bottom border to a View (in particular, a TextView) in Android?
In android 2.2 you could do the following.
Create an xml drawable such as /res/drawable/textlines.xml and assign this as a TextView's background property.
<TextView
android:text="My text with lines above and below"
android:background="#drawable/textlines"
/>
/res/drawable/textlines.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FF000000" />
<solid android:color="#FFDDDDDD" />
</shape>
</item>
<item android:top="1dp" android:bottom="1dp">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#FFDDDDDD" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
The down side to this is that you have to specify an opaque background colour, as transparencies won't work. (At least i thought they did but i was mistaken). In the above example you can see that the solid colour of the first shape #FFdddddd is copied in the 2nd shapes stroke colour.
I've used a trick so that the border is displayed outside the container. With this trick only a line is drawn so the background will be shown of the underlying view.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="1dp"
android:left="-2dp"
android:right="-2dp"
android:top="-2dp">
<shape android:shape="rectangle" >
<stroke
android:width="1dp"
android:color="#FF000000" />
<solid android:color="#00FFFFFF" />
<padding android:left="10dp"
android:right="10dp"
android:top="10dp"
android:bottom="10dp" />
</shape>
</item>
</layer-list>
To add a 1dp white border at the bottom only and to have a transparent background you can use the following which is simpler than most answers here.
For the TextView or other view add:
android:background="#drawable/borderbottom"
And in the drawable directory add the following XML, called borderbottom.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:top="-2dp" android:left="-2dp" android:right="-2dp">
<shape android:shape="rectangle">
<stroke android:width="1dp" android:color="#ffffffff" />
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
If you want a border at the top, change the android:top="-2dp" to android:bottom="-2dp"
The colour does not need to be white and the background does not need to be transparent either.
The solid element may not be required. This will depend on your design (thanks V. Kalyuzhnyu).
Basically, this XML will create a border using the rectangle shape, but then pushes the top, right and left sides beyond the render area for the shape. This leaves just the bottom border visible.
Option 1: Shape Drawable
This is the simplest option if you want a border around a layout or view in which you can set the background. Create an XML file in the drawable folder that looks something like this:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#8fff93" />
<stroke
android:width="1px"
android:color="#000" />
</shape>
You can remove the solid if you don't want a fill. The set background="#drawable/your_shape_drawable" on your layout/view.
Option 2: Background View
Here's a little trick I've used in a RelativeLayout. Basically you have a black square under the view you want to give a border, and then give that view some padding (not margin!) so the black square shows through at the edges.
Obviously this only works properly if the view doesn't have any transparent areas. If it does I would recommend you write a custom BorderView which only draws the border - it should only be a few dozen lines of code.
<View
android:id="#+id/border"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/image"
android:layout_alignLeft="#+id/image"
android:layout_alignRight="#+id/image"
android:layout_alignTop="#+id/main_image"
android:background="#000" />
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_...
android:padding="1px"
android:src="#drawable/..." />
If you're wondering, it does work with adjustViewBounds=true. However, it doesn't work if you want to have a background in an entire RelativeLayout, because there is a bug that stops you filling a RelativeLayout with a View. In that case I'd recommend the Shape drawable.
Option 3: 9-patch
A final option is to use a 9-patch drawable like this one:
You can use it on any view where you can set android:background="#drawable/...". And yes it does need to be 6x6 - I tried 5x5 and it didn't work.
The disadvantage of this method is you can't change the colours very easily, but if you want fancy borders (e.g. only a border at the top and bottom, as in this question) then you may not be able to do them with the Shape drawable, which isn't very powerful.
Option 4: Extra views
I forgot to mention this really simple option if you only want borders above and below your view. You can put your view in a vertical LinearLayout (if it isn't already) and then add empty Views above and below it like this:
<View android:background="#000" android:layout_width="match_parent" android:layout_height="1px"/>
The currently accepted answer doesn't work. It creates thin vertical borders on the left and right sides of the view as a result of anti-aliasing.
This version works perfectly. It also allows you to set the border widths independently, and you can also add borders on the left / right sides if you want. The only drawback is that it does NOT support transparency.
Create an xml drawable named /res/drawable/top_bottom_borders.xml with the code below and assign it as a TextView's background property.
<?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="#DDDD00" /> <!-- border color -->
</shape>
</item>
<item
android:bottom="1dp"
android:top="1dp"> <!-- adjust borders width here -->
<shape android:shape="rectangle">
<solid android:color="#FFFFFF" /> <!-- background color -->
</shape>
</item>
</layer-list>
Tested on Android KitKat through Marshmallow
So I wanted to do something slightly different: a border on the bottom ONLY, to simulate a ListView divider. I modified Piet Delport's answer and got this:
<?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="#color/background_trans_light" />
</shape>
</item>
<!-- this mess is what we have to do to get a bottom border only. -->
<item android:top="-2dp"
android:left="-2dp"
android:right="-2dp"
android:bottom="1px">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#color/background_trans_mid" />
<solid android:color="#null" />
</shape>
</item>
</layer-list>
Note using px instead of dp to get exactly 1 pixel divider (some phone DPIs will make a 1dp line disappear).
Add file to res/drawable
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="-2dp" android:right="-2dp">
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#000000" />
</shape>
</item>
</layer-list>
Add link on this file to background property
Just as #Nic Hubbard said, there is a very easy way to add a border line.
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#000000" >
</View>
You can change the height and background color to whatever you want.
You can also wrap the view in a FrameLayout, then set the frame's background color and padding to what you want; however, the textview, by default has a 'transparent' background, so you'd need to change the textview's background color too.
My answers is based on #Emile version but I use transparent color instead of solid.
This example will draw a 2dp bottom border.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#50C0E9" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
<item android:bottom="2dp" >
<shape android:shape="rectangle" >
<stroke android:width="2dp"
android:color="#color/bgcolor" />
<solid android:color="#android:color/transparent" />
</shape>
</item>
</layer-list>
#color/bgcolor is the color of the background on wich you draw your view with border.
If you want to change the position of the border change the offset with one of:
android:bottom="2dp"
android:top="2dp"
android:right="2dp"
android:left="2dp"
or combine them to have 2 or more borders:
android:bottom="2dp" android:top="2dp"
You can do this by this code snippet -
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!--Minus (-) how much dp you gave in the stroke width from left right-->
<item android:left="-10dp" android:right="-10dp">
<shape
android:shape="rectangle">
<stroke android:width="10dp" android:color="#android:color/holo_red_dark" />
<!--This is the main background -->
<solid android:color="#FFDDDDDD" />
</shape>
</item>
</layer-list>
Preview -
Why not just create a 1dp high view with a background color? Then it can be easily placed where you want.
To change this:
<TextView
android:text="My text"
android:background="#drawable/top_bottom_border"/>
I prefer this approach in "drawable/top_bottom_border.xml":
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="270"
android:startColor="#000"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="90"
android:startColor="#000"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />
</shape>
</item>
</layer-list>
This only makes the borders, not a rectangle that will appear if your background has a color.
Simplest way to add borders to inset the borders using InsetDrawable,following will show top border only :
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetBottom="-2dp"
android:insetLeft="-2dp"
android:insetRight="-2dp">
<shape android:shape="rectangle">
<solid android:color="#color/light_gray" />
<stroke
android:width=".5dp"
android:color="#color/dark_gray" />
</shape>
</inset>
Just to add my solution to the list..
I wanted a semi transparent bottom border that extends past the original shape (So the semi-transparent border was outside the parent rectangle).
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle" >
<solid android:color="#33000000" /> <!-- Border colour -->
</shape>
</item>
<item android:bottom="2dp" >
<shape android:shape="rectangle" >
<solid android:color="#164586" />
</shape>
</item>
</layer-list>
Which gives me;
First make a xml file with contents shown below and name it border.xml and place it inside the layout folder inside the res directory
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="1dp" android:color="#0000" />
<padding android:left="0dp" android:top="1dp" android:right="0dp"
android:bottom="1dp" />
</shape>
After that inside the code use
TextView tv = (TextView)findElementById(R.id.yourTextView);
tv.setBackgroundResource(R.layout.border);
This will make a black line on top and bottom of the TextView.
Simply add Views at the top and bottom of the View
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/your_color"
app:layout_constraintBottom_toTopOf="#+id/textView"
app:layout_constraintEnd_toEndOf="#+id/textView"
app:layout_constraintStart_toStartOf="#+id/textView" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:gravity="center"
android:text="Testing"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/your_color"
app:layout_constraintEnd_toEndOf="#+id/textView"
app:layout_constraintStart_toStartOf="#+id/textView"
app:layout_constraintTop_toBottomOf="#+id/textView" />
</android.support.constraint.ConstraintLayout>
Write down below code
<View
android:layout_width="wrap_content"
android:layout_height="2dip"
android:layout_below="#+id/topics_text"
android:layout_marginTop="7dp"
android:layout_margin="10dp"
android:background="#ffffff" />
Try wrapping the image with a linearlayout, and set it's background to the border color you want around the text. Then set the padding on the textview to be the thickness you want for your border.
You can also use a 9-path to do your job. Create it so that colored pixel do not multiply in height but only the transparent pixel.
Based on accepted answer of Pi Delport and Emile, I made it a little simpler
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item> <!--divider TOP and BOTTOM-->
<shape android:shape="rectangle">
<stroke
android:width="1dp"
android:color="#color/divider" />
</shape>
</item>
<!--background surface-->
<item
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="#color/background" />
</shape>
</item>
// Just simply add border around the image view or view
<ImageView
android:id="#+id/imageView2"
android:layout_width="90dp"
android:layout_height="70dp"
android:layout_centerVertical="true"
android:layout_marginRight="10dp"
android:layout_toLeftOf="#+id/imageView1"
android:background="#android:color/white"
android:padding="5dip" />
// After that dynamically put color into your view or image view object
objView.setBackgroundColor(Color.GREEN);
//VinodJ/Abhishek
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/light_grey1" />
<stroke
android:width="1dip"
android:color="#color/light_grey1" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
</shape>
<TextView
android:id="#+id/textView3"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#72cdf4"
android:text=" aa" />
Just Add this TextView below the text where you want to add the border
Just to enforce #phreakhead ´s and user1051892 ´s answers, <item android:bottom|android:left|android:right|android:top> if negative, must to be greater than <stroke android:width>. If not, item´s painting will be mixed with stroke´s painting and you may think these values are not working.

Categories

Resources