I am trying to implement in XML a ShapeDrawable like this, but so far without success.
How do I make the Stroke visible only for two sides?
Is that even possible?
Otherwise what cloud I use (I seed it as background of a TextView).
Here is a solution which is using a LayerListDrawable:
background_white_lateral_border.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="#android:color/white" />
</shape>
</item>
<item>
<inset
android:insetLeft="1dp"
android:insetRight="1dp" >
<shape android:shape="rectangle" >
<solid android:color="#android:color/black" />
</shape>
</inset>
</item>
</layer-list>
Note: This firstly draws a white rectangle and then a black rectangle with a left and right inset of 1dp on top of it, giving the effect of lateral borders. It's just something to keep in mind, in case you worry about performance (which is in my opinion negligible for minor styling like this).
AFAIK, that is not possible with a single ShapeDrawable. A nine-patch PNG, or a LayerListDrawable of two ShapeDrawables (one per line) should work though.
Related
Hi I'm trying to make a drawable which looks like a small vertical line with a circle attached to the bottom of it. I am trying to figure out if creating such a shape in a single xml file is possible (I know I could probably place two shapes on top of each other but I'm trying to avoid doing that)
Here's what I have so far:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/line">
<shape
android:shape="line"
>
<stroke
android:width="2dp"
android:color="#000000" />
<size android:height="12dp"/>
</shape>
</item>
<item
android:top="5px"
android:id="#+id/circle">
<shape
android:shape="oval"
android:useLevel="false"
android:innerRadius="5dp"
android:thickness="2dp"
>
<solid
android:color="#color/silver_status"
></solid>
<stroke
android:color="#color/silver_status"
android:width="1dp"
/>
</shape>
</item>
</layer-list>
This layers the two images on top of each other (I think) but what I really want is for them to be on top of each other
Anyone know if this is possible/how it can be done?
I ended up solving this simply by using the individual shapes within a linear layout to achieve the affect. Not exactly what I wanted but definitely does the job just fine.
I've got two shape drawable xml files that I am using on imagebuttons. One contains a ring, the other contains an oval small enough to fit into the larger ring, similar to a radiobutton. In this image http://imgur.com/mYPALoT you can see (from left to right) the ring, the smaller middle oval, and the combined image showing the layerlist view of both together. This doesn't work and instead shows a complete filled in oval.
Here is the ring xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="ring"
android:innerRadiusRatio="3"
android:thickness="1dp"
android:useLevel="false">
<solid android:color="#1976D2" />
<size
android:height="20dp"
android:width="20dp" />
</shape>
Here is the oval xml:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#1976D2" />
<size
android:height="7dp"
android:width="7dp" />
</shape>
Here is the layerlist xml:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ring_select" />
<item android:drawable="#drawable/ring_center" />
</layer-list>
I'm not familiar with layerlists as I am new to android. What am I doing wrong?
In case another person descends upon this page by the guiding of the knowledegable Google...
I have a workaround that may or may not work for you: instead of using <scale> , try <inset>. You can use a combination of the <item>'s android:top / android:bottom / android:left / android:right and the <inset>'s android:insetXXX to size the image
You can do things like set the sides of each inset value relative to your source image's dimensions. For example, if you have a 64 pixel-wide image and want to cut it down by 50%, you can do (64 / 4 = 16) for each side
I finally found the answer. Basically, the oval in front needs to have this added to it's line:
<item android:top="10dp" android:bottom="10dp" android:left="10dp" android:right="10dp">
The dimensions need to be the same since this is an oval. I'm still not sure why the oval stretched to the entire size of the ring, especially since the size was defined. If anyone has any idea why the top oval stretched like that, please let me know.
I created a rather simple shapedrawable with semi-transparent borders, and used it as a background for two adjacent view.
Either if the srtoke color is partially transparent, I'm expecting a solid stroke (like the image on the right), but what I get is a blurred stroke (image on the left).
What I'm doing wrong?
(images are taken from the ADT preview, in the emulator the effect is even more visible)
This is the ShapeDrawable (theme_base_bg_framed.xml):
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/base_frame_solid_color"
/>
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
<padding
android:left="#dimen/frame_padding_size"
android:top="#dimen/frame_padding_size"
android:right="#dimen/frame_padding_size"
android:bottom="#dimen/frame_padding_size"
/>
</shape>
It uses these color and dimen definitions:
<color name="base_frame_solid_color">#20ffffff</color>
<color name="base_frame_border_color">#40ffffff</color>
<dimen name="frame_border_size">2dp</dimen>
<dimen name="frame_padding_size">2dp</dimen>
Both drawables are assigned to the Views background
<style name="ViewWithBorder">
<item name="android:background">#drawable/theme_base_bg_framed</item>
</style>
Edit:
The colors used in the ShapeDrawable are alphaed for a reason. The view in the background is going to contain other views and/or images. This is a better example of what I get (left) and what I'm expecting to get (right).
I use this values to get the result you wanted:
colors.xml:
<color name="base_frame_solid_color">#20000000</color>
<color name="base_frame_border_color">#40ffffff</color>
shape:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#color/base_frame_solid_color"
/>
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
</shape>
Hope this helps!
Ok, I found what's happening and how to fix it.
It seems that Android, when filling a ShapeDrawable with a border, doesn't fill it to it's full size but just to the middle of the stroke. So, with a stroke of 2dp, it leave a space of 1dp all around. This can be noticed only when using alphaed borders, like I'm doing, because normally the border cover it.
Tho fix this behaviour, I used a LayerList drawable containing two ShapeDrawables, one for the solid color (with no borders) and one for the stroke (with no solid color):
<?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/base_frame_solid_color"
/>
</shape>
</item>
<item>
<shape
android:shape="rectangle">
<stroke
android:width="#dimen/frame_border_size"
android:color="#color/base_frame_border_color"
/>
<padding
android:left="#dimen/frame_padding_size"
android:top="#dimen/frame_padding_size"
android:right="#dimen/frame_padding_size"
android:bottom="#dimen/frame_padding_size"
/>
</shape>
</item>
</layer-list>
It works, but being the border superimposed to the "solid" background, it's color need some adjustment.
I'm trying to define a background drawable in XML that will make the background have a 1dp grey border on the left. The XML I'm using is:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#00FFFFFF" />
<stroke android:width="1dp" android:color="#CCCCCC" />
<padding android:left="1dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
In the screenshot below you can see that it's actually putting a 1dp border around the entire view (the "Recent Lessons" area):
Can someone explain to me what I've done wrong here?
I think that you may have confused padding and stroke. The 1dp stroke you are adding is the border you see around the shape - not the padding. Try following these examples. For more about LayerList see the android docs (LayerList section). Basically, it boils down to multiple drawables as one.
Is it possible to draw a left and bottom border for a textview?
You can put the TextView inside of another layout with an XML shape similar to the one below:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<solid android:color="#color/detailtable_border" />
</shape>
</item>
<item android:left="1.5dp" android:right="1.5dp" android:bottom="2dp">
<shape android:shape="rectangle">
<solid android:color="#color/detailrow_bg_normal" />
</shape>
</item>
</layer-list>
You can create a 9-path to be your TextView's BG. That 9-patch will have only left and bottom border, so it'll suit your needs. You can read more on 9-patches here: http://developer.android.com/guide/developing/tools/draw9patch.html
You can use the draw9patch tool on the SDK do draw your own 9patch, or take en existing 9patch from the Android source code, or even from the other places on the internet, like this blog http://android9patch.blogspot.co.il/ which also have some tutorials on how to create 9 patched.