<size> attribute not useful when using layer-list? - android

Given I have a background drawable to create bulletpoints for TextViews like this:
Then my XML code looks like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="235dp">
<shape android:shape="oval">
<padding android:left="10dp" />
<size android:height="5dp" android:width="5dp"/>
<solid android:color="#color/my_pink"/>
</shape>
</item>
<item android:left="10dp">
<shape android:shape="rectangle">
<solid android:color="#ffffff"/>
<padding android:left="10dp" />
</shape>
</item>
</layer-list>
But once I use the code shown above, my bullet points look like this:
It seems the <size> tag is ignored completely.
How would you solve this problem? Using a 9patch, yes I know.. perhaps that's the easiest to do.. but in fact I was hoping to find a XML solution as it's more flexible in the future.
Custom drawing is also out of the question.

<size> tag certainly works in layer-list
and to show the bullet points for textviews you can use the xml attribute android:drawableLeft
-> link
With this approach, there is no need of 9-patch and custom drawing.
Posting code & screenshot here for the reference.
res/drawable/bullet_point_layer.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:right="3dp">
<shape android:shape="oval">
<padding android:left="10dp" />
<size android:height="10dp" android:width="10dp"/>
<solid android:color="#ff0080"/>
</shape>
</item>
res/layout/main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView one"
android:textColor="#android:color/black"
android:drawableLeft="#drawable/bullet_point_layer"
android:background="#android:color/white" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView Two"
android:textColor="#android:color/black"
android:drawableLeft="#drawable/bullet_point_layer"
android:background="#android:color/white" />
</LinearLayout>
How it looks

This is an old post but I thought I would add something very important which is missing on this post.
From my experience the last item of the <layer-list> will be the item which the size value is taken from.
So in this example I create a two line divider line. I specify an empty item at the end to specify the divider drawable height.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="#535353" />
</shape>
</item>
<item android:top="#dimen/common_divider_line_half_size">
<shape android:shape="rectangle">
<solid android:color="#737373" />
</shape>
</item>
<!-- Last item empty to specify divider height -->
<item>
<shape android:shape="rectangle">
<size android:height="#dimen/common_divider_line_size"/>
<solid android:color="#android:color/transparent" />
</shape>
</item>
</layer-list>

Related

Android: Drawable vertically alignment for SeekBar

This is waht I need to achieve with xml drawable for SeekBar:
I tried many different variations and this is best I could make.
This is seekbar_thumb_drawable.xml:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval" >
<solid android:color="#color/accent_color"/>
<size
android:height="20dp"
android:width="20dp" />
</shape>
This is seekbar_drawable.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:height="5dp"
android:top="7.5dp">
<shape
android:shape="rectangle">
<solid android:color="#color/seekbar_background" />
<corners android:radius="2.5dp" />
</shape>
</item>
<item
android:id="#android:id/progress"
android:height="10dp"
android:top="5dp">
<clip>
<shape
android:shape="rectangle">
<solid android:color="#color/seekbar_progress" />
<corners android:radius="5dp" />
</shape>
</clip>
</item>
</layer-list>
Result on API 18:
Problem is that lines are not verticaly centered.
Result on API 24:
This display exactly how I want it to display.
Is there any possible solution to make this appear as on first picture on all devices from API 16?
I do not want to use nine-patch, because I need to use color from resources.
I tried padding, gravity, top, bottom, inter-shape, line, rectangle but I could not find solution...
This is because the android:height and android:width for <item> are only available for API 23 and above. If you use these attributes for API below 23, it will not give you an error, but simply ignore it.
In your case, android:height="5dp", and android:height="10dp" are not being applied.
If you look at the relevant docs or , it says that these were added in API level 23.
Make update in your drawable files.
In seekbar_thumb_drawable.xml :
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:gravity="center">
<shape android:shape="oval">
<solid android:color="#color/accent_color" />
<size
android:width="20dp"
android:height="20dp" />
</shape>
</item>
</layer-list>
seekbar_drawable.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:height="5dp"
android:gravity="center">
<shape android:shape="rectangle">
<solid android:color="#color/seekbar_background" />
<corners android:radius="2.5dp" />
</shape>
</item>
<item
android:id="#android:id/progress"
android:height="10dp"
android:gravity="center">
<clip>
<shape android:shape="rectangle">
<solid android:color="#color/seekbar_progress" />
<corners android:radius="5dp" />
</shape>
</clip>
</item>
</layer-list>
I m using gravity in item, So that drawable item draw in center.
You probably faced with already known issue, here is the solution for it. You should define maxHeight and minHeight of the SeekBar the same as the height of it. Or you can even set maxHeight to some big value like 1000dp, if you exepect your height to be wrap_content, like mentioned below the suggested answer in the same thread.
<SeekBar
android:thumb="#drawable/seekbar_thumb_drawable"
android:progressDrawable="#drawable/seekbar_drawable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="1000dp"
<!-- OR -->
android:maxHeight="16dp"
android:minHeight="16dp"/>
<SeekBar
android:id="#+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxHeight="3dp"
android:minHeight="3dp"
android:progressDrawable="#drawable/nnl_bg_seek_bar_progress"
android:splitTrack="false"
android:thumb="#drawable/nnl_sel_seek_bar_thumb"
tools:ignore="UnusedAttribute"
/>
The code above is my way. You may need to pay attention to these attributes: maxHeight / minHeight / splitTrack.
I am also facing same issue in Low API of thumb drawable come above the line So what I did for it.
<SeekBar
android:id="#+id/seekbar_transparency"
android:layout_width="match_parent"
android:layout_height="40dp"
android:paddingTop="#dimen/seekbar_thumb_size_space"
android:paddingBottom="#dimen/seekbar_thumb_size_space"
android:progress="100"
android:theme="#style/SeekbarTheme"
android:thumb="#drawable/thumb_drawable" />
style.xml
<!--Seekbar background change-->
<style name="SeekbarTheme" parent="Theme.AppCompat.Light">
<!-- active seekbar progress track color -->
<item name="colorControlActivated">#color/colorSeekBar</item>
<!-- inactive seekbar progress track color -->
<item name="colorControlNormal">#color/colorGray</item>
</style>
thumb_drawable.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:bottom="2.5dp"
android:left="2.5dp"
android:right="2.5dp"
android:top="2.5dp">
<shape android:shape="rectangle">
<size
android:width="#dimen/seekbar_thumb_size"
android:height="#dimen/seekbar_thumb_size" />
<corners android:radius="20dp" />
<solid android:color="#201DE9B6" />
</shape>
</item>
<item
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp">
<shape android:shape="rectangle">
<size
android:width="#dimen/seekbar_thumb_size"
android:height="#dimen/seekbar_thumb_size" />
<corners android:radius="20dp" />
<solid android:color="#AA1DE9B6" />
</shape>
</item>
</layer-list>
dimes.xml
<!--Seeckbar thumb size-->
<dimen name="seekbar_thumb_size">10dp</dimen>
<dimen name="seekbar_thumb_size_space">5dp</dimen>

Android draw circle and wrap around text on Textview

I have a textview containing numbers 1,2,3.... I want to have a circle around the numbers, something along the lines of;
The code for my textview is;
<TextView
android:id="#+id/position"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_weight="0.20"
android:textStyle="bold"
android:layout_gravity="center"
android:layout_margin="5dp"
android:background="#drawable/circlebg"
android:textSize="20dp"/>
and I have a xml background file, which contains;
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<corners android:radius="10dip"/>
<stroke android:color="#ff0000" android:width="2dip"/>
<solid android:color="#android:color/transparent"/>
</shape>
the outcome of this is;
What I want to know is how can I get the result of this to be like shown in the first screenshot. Any help is welcomed.
activity.xml
<Button
android:id="#+id/fragment_pos_inventory_Add"
android:layout_width="25dp"
android:layout_height="25dp"
android:background="#drawable/layer_list" />
layer_list.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="false">
<shape android:shape="oval">
<solid android:color="#fa09ad" />
</shape>
</item>
<item android:state_pressed="true">
<shape android:shape="oval">
<solid android:color="#ffffff"/>
<padding android:left="2dp"
android:right="2dp"
android:top="2dp"
android:bottom="2dp"/>
</shape>
</item>
</layer-list>
Have you tried ViewBadger or BadgeView? These may help you. You can later make changes on that.
You are on the right track, all you have to do is make the textview's layout_height and layout_width a fixed value e.g 50dp, instead of using "wrap_content". When the textView's layout_height and layout_width are equal, you get a circle.

Android LinearLayout : Add border with shadow around a LinearLayout

I would like to create the same border of this LinearLayout as the example :
In this example, we can see that the border is not the same all around the linearLayout.
How can I create this using an XML drawable file?
For now, I have only able to create a simple border all around the LinearLayout like this :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners
android:radius="1dp"
android:topRightRadius="0dp"
android:bottomRightRadius="0dp"
android:bottomLeftRadius="0dp" />
<stroke
android:width="1dp"
android:color="#E3E3E1" />
<solid android:color="#color/blanc" />
</shape>
Try 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="#CABBBBBB"/>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
That's why CardView exists. CardView | Android Developers
It's just a FrameLayout that supports elevation in pre-lollipop devices.
<android.support.v7.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardUseCompatPadding="true"
app:cardElevation="4dp"
app:cardCornerRadius="3dp" >
<!-- put whatever you want -->
</android.support.v7.widget.CardView>
To use this you need to add dependency to build.gradle:
compile 'com.android.support:cardview-v7:23.+'
I get the best looking results by using a 9 patch graphic.
You can simply create an individual 9 patch graphic by using the following editor:
http://inloop.github.io/shadow4android/
Example:
The 9 patch graphic:
The result:
The source:
<LinearLayout
android:layout_width="200dp"
android:layout_height="200dp"
android:orientation="vertical"
android:background="#drawable/my_nine_patch"
okay, i know this is way too late. but i had the same requirement. i solved like this
1.First create a xml file (example: border_shadow.xml) in "drawable"
folder and copy the below code into it.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<item>
<shape>
<!-- set the shadow color here -->
<stroke
android:width="2dp"
android:color="#7000" />
<!-- setting the thickness of shadow (positive value will give shadow on that side) -->
<padding
android:bottom="2dp"
android:left="2dp"
android:right="-1dp"
android:top="-1dp" />
<corners android:radius="3dp" />
</shape>
</item>
<!-- Background -->
<item>
<shape>
<solid android:color="#fff" />
<corners android:radius="3dp" />
</shape>
</item>
</layer-list>
2.now on the layout where you want the shadow(example: LinearLayout) add this in android:background
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="8dip"
android:background="#drawable/border_shadow"
android:orientation="vertical">
and that worked for me.
This is so simple:
Create a drawable file with a gradient like this:
for shadow below a view below_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#20000000"
android:endColor="#android:color/transparent"
android:angle="270" >
</gradient>
</shape>
for shadow above a view above_shadow.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#20000000"
android:endColor="#android:color/transparent"
android:angle="90" >
</gradient>
</shape>
and so on for right and left shadow just change the angle of the gradient :)
As an alternative, you might use a 9 patch image as the background for your layout, allowing for more "natural" shadows:
Result:
Put the image in your /res/drawable folder.
Make sure the file extension is .9.png, not .png
By the way, this is a modified (reduced to the minimum square size) of an existing resource found in the API 19 sdk resources folder.
I left the red markers, since they don't seem to be harmful, as shown in the draw9patch tool.
[EDIT]
About 9 patches, in case you never had anything to do with them.
Simply add it as the background of your View.
The black-marked areas (left and top) will stretch (vertically, horizontally).
The black-marked areas (right, bottom) define the "content area" (where it's possible to add text or Views - you can call the unmarked regions "padding", if you like to).
Tutorial: http://radleymarx.com/blog/simple-guide-to-9-patch/
You create a file .xml in drawable with name drop_shadow.xml:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!--<item android:state_pressed="true">
<layer-list>
<item android:left="4dp" android:top="4dp">
<shape>
<solid android:color="#35000000" />
<corners android:radius="2dp"/>
</shape>
</item>
...
</layer-list>
</item>-->
<item>
<layer-list>
<!-- SHADOW LAYER -->
<!--<item android:top="4dp" android:left="4dp">
<shape>
<solid android:color="#35000000" />
<corners android:radius="2dp" />
</shape>
</item>-->
<!-- SHADOW LAYER -->
<item>
<shape>
<solid android:color="#35000000" />
<corners android:radius="2dp" />
</shape>
</item>
<!-- CONTENT LAYER -->
<item android:bottom="3dp" android:left="1dp" android:right="3dp" android:top="1dp">
<shape>
<solid android:color="#ffffff" />
<corners android:radius="1dp" />
</shape>
</item>
</layer-list>
</item>
</selector>
Then:
<LinearLayout
...
android:background="#drawable/drop_shadow"/>
1.First create a xml file name shadow.xml in "drawable" folder and copy the below code into it.
<?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="#CABBBBBB" />
<corners android:radius="10dp" />
</shape>
</item>
<item
android:bottom="6dp"
android:left="0dp"
android:right="6dp"
android:top="0dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white" />
<corners android:radius="4dp" />
</shape>
</item>
</layer-list>
Then add the the layer-list as background in your LinearLayout.
<LinearLayout
android:id="#+id/header_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/shadow"
android:orientation="vertical">
Use this single line and hopefully you will achieve the best result;
use:
android:elevation="3dp" Adjust the size as much as you need and this is the best and simplest way to achieve the shadow like buttons and other default android shadows.
Let me know if it worked!
If you already have the border from shape just add elevation:
<LinearLayout
android:id="#+id/layout"
...
android:elevation="2dp"
android:background="#drawable/rectangle" />
Ya Mahdi aj---for RelativeLayout
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient
android:startColor="#7d000000"
android:endColor="#android:color/transparent"
android:angle="90" >
</gradient>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="3dp"
android:top="0dp"
android:bottom="3dp">
<shape android:shape="rectangle">
<padding
android:bottom="40dp"
android:top="40dp"
android:right="10dp"
android:left="10dp"
>
</padding>
<solid android:color="#color/Whitetransparent"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
I know this is late but it could help somebody.
You can use a constraintLayout and add the following property in the xml,
android:elevation="4dp"
I found the best way to tackle this.
You need to set a solid rectangle background on the layout.
Use this code - ViewCompat.setElevation(view , value)
On the parent layout set android:clipToPadding="false"

How to create Google + cards UI in a list view?

I want to create a listView of cards, but after reading this blog post goolge-plus-layout, I'm cards are a viable solution for a list of anything. The animation part seems too memory intensive to load say a listview with more than 40 elements simultaneously.
Is there a better way to achieve a cards UI in listView?
You can create a custom drawable, and apply that to each of your listview elements.
I use this one for cards in my UI. I don't think there is significant performance issues with this approach.
The drawable code (in drawable\big_card.xml) looks like 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/second_grey" />
</shape>
</item>
<item
android:bottom="10dp"
android:left="10dp"
android:right="10dp"
android:top="10dp">
<shape android:shape="rectangle" >
<corners android:radius="3dp" />
<solid android:color="#color/card_shadow" />
</shape>
</item>
<item
android:bottom="12dp"
android:left="10dp"
android:right="10dp"
android:top="10dp">
<shape android:shape="rectangle" >
<corners android:radius="3dp" />
<solid android:color="#color/card_white" />
</shape>
</item>
</layer-list>
I apply the background to my listview elements like this:
<ListView
android:id="#+id/apps_fragment_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:listSelector="#drawable/big_card" />
If you want to add this as a background to any View (not just a list), you just make the custom drawable that View's background element:
<TextView
android:id="#+id/any_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#drawable/big_card" />
EDIT: Google provides a nice class called CardView. I didn't check it but it looks promising.
Here's the previous way, which also works fine (that's what I wrote before the edit) :
There is a nice tutorial here and a nice sample of it here .
in short , these are the files you can create:
listView definition:
android:divider="#null"
android:dividerHeight="10dp"
android:listSelector="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
android:headerDividersEnabled="true"
android:footerDividersEnabled="true"
also this:
m_list.addHeaderView(new View(this));
m_list.addFooterView(new View(this));
res/drawable/selector_card_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_pressed="true"
android:drawable="#drawable/layer_card_background_selected" />
<item android:drawable="#drawable/layer_card_background" />
</selector>
listView item :
res/layout/list_item_card.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingRight="15dp"
android:descendantFocusability="beforeDescendants">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="15dp"
android:paddingTop="15dp"
android:paddingBottom="15dp"
android:paddingRight="15dp"
android:background="#drawable/selector_card_background"
android:descendantFocusability="afterDescendants">
<TextView
android:id="#+id/text1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="#+id/text3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</FrameLayout>
res/drawable/layer_card_background_selected.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="#CABBBBBB"/>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#CCCCCC"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
res/drawable/layer_card_background.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="#CABBBBBB"/>
<corners android:radius="2dp" />
</shape>
</item>
<item
android:left="0dp"
android:right="0dp"
android:top="0dp"
android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#android:color/white"/>
<corners android:radius="2dp" />
</shape>
</item>
</layer-list>
If all you want is a ListView that simulates the cards-look you can use a 9-patch as background for your listitems to make them look like cards. You can find a 9-patch and some more tips and explanation here: http://www.tiemenschut.com/simply-get-cards-ui-look/
Add divider for the Listview item and padding :
android:divider="#android:color/transparent"
android:dividerHeight="1dip"
Add RelativeLayout into your LinearLayout for ListItem with some desired padding :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:orientation="vertical"
android:padding="3dp" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/rowshadow" >
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
Add Background to the listview item , like :
<?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/darker_gray" />
<corners android:radius="0dp"/>
</shape>
</item>
<item android:right="1dp" android:left="1dp" android:bottom="2dp">
<shape
android:shape="rectangle">
<solid android:color="#android:color/white"/>
<corners android:radius="0dp"/>
</shape>
</item>
</layer-list>
Use https://github.com/elcrion/demo.cardlistview as an example. It is somehow close to google style
As "android developer" briefly mentions in his answer, the CardView class can be used to easily create card views.
Just wrap you UI widgets in a CardView element and you are ready to go. See the short introduction to the CardView widget at https://developer.android.com/training/material/lists-cards.html#CardView.
The CardView class requires a v7 support library, remember to add the dependencies to your .gradle file!
compile 'com.android.support:cardview-v7:21.0.+'

How to draw border on just one side of a linear layout?

I'm able to draw border to a linear layout, but it is getting drawn on all sides. I want to restrict it to right side only, like you do in CSS (border-right:1px solid red;).
I've tried this, but it still draws on all sides:
<?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:height="2dp"
android:width="2dp"
android:color="#FF0000" />
<solid android:color="#000000" />
<padding
android:bottom="0dp"
android:left="0dp"
android:right="1dp"
android:top="0dp" />
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="5dp"
android:radius="1dp"
android:topLeftRadius="5dp"
android:topRightRadius="0dp" />
</shape>
</item>
Any suggestions on how to accomplish this?
BTW, I do not want to use the hack of putting a view of width 1dp on the required side.
You can use this to get border on one side
<?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="#FF0000" />
</shape>
</item>
<item android:left="5dp">
<shape android:shape="rectangle">
<solid android:color="#000000" />
</shape>
</item>
</layer-list>
EDITED
As many including me wanted to have a one side border with transparent background, I have implemented a BorderDrawable which could give me borders with different size and color in the same way as we use css. But this could not be used via xml. For supporting XML, I have added a BorderFrameLayout in which your layout can be wrapped.
See my github for the complete source.
Easy as pie, allowing a transparent bg:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="0"
android:startColor="#f00"
android:centerColor="#android:color/transparent"
android:centerX="0.01" />
</shape>
Change the angle to change border location:
0 = left
90 = bottom
180 = right
270 = top
it is also possible to implement what you want using a single layer
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:bottom="-5dp"
android:right="-5dp"
android:top="-5dp">
<shape android:shape="rectangle" >
<solid android:color="#color/color_of_the_background" />
<stroke
android:width="5dp"
android:color="#color/color_of_the_border" />
</shape>
</item>
</layer-list>
this way only left border is visible but you can achieve any combination you want by playing with bottom, left, right and top attributes of the item element
To get a border on just one side of a drawable, apply a negative inset to the other 3 sides (causing those borders to be drawn off-screen).
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="-2dp"
android:insetBottom="-2dp"
android:insetLeft="-2dp">
<shape android:shape="rectangle">
<stroke android:width="2dp" android:color="#FF0000" />
<solid android:color="#000000" />
</shape>
</inset>
This approach is similar to naykah's answer, but without the use of a layer-list.
An other great example
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetRight="-2dp">
<shape android:shape="rectangle">
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="4dp"
android:topRightRadius="0dp" />
<stroke
android:width="1dp"
android:color="#70b23f" />
<solid android:color="#android:color/transparent" />
</shape>
</inset>
As an alternative (if you don't want to use background), you can easily do it by making a view as follows:
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#000000" />
For having a right border only, place this after the layout (where you want to have the border):
<View
android:layout_width="2dp"
android:layout_height="match_parent"
android:background="#000000" />
For having a left border only, place this before the layout (where you want to have the border):
Worked for me...Hope its of some help....
I was able to achieve the effect with the following code
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:left="0dp" android:right="-5dp" android:top="-5dp" android:bottom="-5dp">
<shape
android:shape="rectangle">
<stroke android:width="1dp" android:color="#123456" />
</shape>
</item>
</layer-list>
You can adjust to your needs for border position by changing the direction of displacement
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" >
<shape>
<solid
android:color="#f28b24" />
<stroke
android:width="1dp"
android:color="#f28b24" />
<corners
android:radius="0dp"/>
<padding
android:left="0dp"
android:top="0dp"
android:right="0dp"
android:bottom="0dp" />
</shape>
</item>
<item>
<shape>
<gradient
android:startColor="#f28b24"
android:endColor="#f28b24"
android:angle="270" />
<stroke
android:width="0dp"
android:color="#f28b24" />
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="0dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp"/>
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>
</item>
</selector>
There is no mention about nine-patch files here. Yes, you have to create the file, however it's quite easy job and it's really "cross-version and transparency supporting" solution. If the file is placed to the drawable-nodpi directory, it works px based, and in the drawable-mdpi works approximately as dp base (thanks to resample).
Example file for the original question (border-right:1px solid red;) is here:
http://ge.tt/517ZIFC2/v/3?c
Just place it to the drawable-nodpi directory.
Borders of different colors. I used 3 items.
<?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/colorAccent" />
</shape>
</item>
<item android:top="3dp">
<shape android:shape="rectangle">
<solid android:color="#color/light_grey" />
</shape>
</item>
<item
android:bottom="1dp"
android:left="1dp"
android:right="1dp"
android:top="3dp">
<shape android:shape="rectangle">
<solid android:color="#color/colorPrimary" />
</shape>
</item>
</layer-list>
You can wrap into container and define margins for start left bottom top.
Suppose you want to provide margin for left side you can do this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/light_blue"
>
<TextView
android:marginStart="2dp" // This is Your border
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/white"
android:padding="16dp"
android:text="a"
android:textColor="#color/light_blue"
android:textSize="25dp" />
</RelativeLayout>

Categories

Resources