Set width of Android Drawable item? - android

What I wanted was while background with red part on the left. Something like this.
I tried many things (is there any WYSIWIG editor? I think I ran this hundreds of times.) Specifying width like in the following article did not work.
how to specify width and height of a drawable item
The following article only tells me that I cannot use percentage, now how to apply width.
Android Drawable: Specifying shape width in percent in the XML file?
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid
android:color="#FFFFFFFF"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#55FF0000" />
<size android:width="100px" />
</shape>
</item>
</layer-list>

Rather than specify the size of the red box, you would define a red layer and then set the left margin of the white layer equal to the amount of red to show.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#55FF0000" />
</shape>
</item>
<item android:left="100px">
<shape android:shape="rectangle">
<solid android:color="#FFFFFFFF"/>
</shape>
</item>
</layer-list>
If you know the desired negative space, you could even swap the two and set the right margin of the red (now top) layer to the amount of white that should be visible.

Related

Custom drawable speech bubble

I need to create a speech bubble background for an icons container like the white one in this image:
Required Appearance
I decided to use a drawable xml rather than a 9 patch image, so I can control of the rounded corner radii in my code. So, with the help of this answer to a related question, I have created the following xml:
bg_icons_container.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="0dp"
android:top="27dp"> <!-- How to make this 50% of height? -->
<rotate
android:fromDegrees="-45"
android:toDegrees="0"
android:pivotX="0%"
android:pivotY="0%"> <!-- How to make the triangle more acute? -->
<shape
android:shape="rectangle" >
<solid
android:color="#color/white"/>
</shape>
</rotate>
</item>
<item
android:left="10dp">
<shape
android:shape="rectangle">
<solid
android:color="#color/white"/>
<corners
android:radius="#dimen/border_radius_small"/>
</shape>
</item>
</layer-list>
This results in:
Actual Apperance (enlarged)
My problem is that the triangular part of the drawable is too wide. How can I make it more acute? (My minSdkVersion is 16, so I cannot use android_width on the first item to try and stretch it.)
Also, I am having to hard code android:top of the first item to 27dp. Is it possible to make this 50%, so it will correctly adjust when the height of the drawable changes?

Drawable with 2 solid colours

I'm trying to create a drawable to act as the background for one of my layouts, and can't get it to display two solid colours divided in the middle.
Currently I'm attempting to use a layer-list with the background being solid, and an overlay of a semi transparent white rectangle to tint the original solid background colour along the top half of the rectangle. It doesn't need to be done like this though.
Gradient will not work unless you can find a way to make the transition immediate.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<size android:height="#dimen/basic_runners_height"></size>
<solid android:color="#color/brb_orange"
android:gravity="bottom"></solid>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<size android:height="#dimen/basic_runners_height_halved"></size>
<solid android:color="#color/md_white_1000"
android:alpha="127"
android:gravity="top"></solid>
</shape>
</item>
So, my understanding of this is that there should be two shapes, one half the size of the other. The first shape covers the whole drawable in orange and the other is white, and ~50% transparent (alpha = 127), takes up half the drawable and gravitates toward the top.
The preview of the drawable is fully white, without a hint of orange. What am I doing wrong?
Edit:
Right, to make this even simpler, I've added the tinted colour to my #color so that I don't even need to bother with transparency. The XML is as shown below:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:top="#dimen/basic_runners_height_halved">
<shape android:shape="rectangle" >
<size android:height="#dimen/basic_runners_height_halved" />
<solid android:color="#color/brb_orange_tint" />
</shape>
</item>
<item android:top="#dimen/basic_runners_height">
<shape android:shape="rectangle" >
<size android:height="#dimen/basic_runners_height" />
<solid android:color="#color/brb_orange" />
</shape>
</item>
But this doesn't even do the trick... runners_height_halved is half the dp of runners_height but this doesn't split it down the middle. Maybe 10% of the drawable is the tinted colour, and for some reason they are reversed so that the tinted colour is at the bottom. This should be the most simple thing...
Try to use padding(top,left, right, bottom) in the <item> tag. Hope it helps
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<size android:height="#dimen/basic_runners_height"></size>
<solid android:color="#color/brb_orange"
android:gravity="bottom"></solid>
</shape>
</item>
<item android:top="10dp"
android:left="10dp"
android:right="10dp"
android:bottom="10dp">
<shape android:shape="rectangle">
<size android:height="#dimen/basic_runners_height_halved"></size>
<solid android:color="#color/md_white_1000"
android:alpha="127"
android:gravity="top"></solid>
</shape>
</item>

Drawable half-half colors / Only xml

Is it possible to create a drawable (I guess a layer-list) splitted by two:
Half color (half left) be e.g. red, other right be green. But not use fixed dp values.
Think of like we can do with android-weigth for Linear and Relative layouts, but a drawable.
Is something like that possible only with XML code?
try this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#0f0" />
</shape>
</item>
<item>
<clip>
<shape>
<solid android:color="#f00" />
</shape>
</clip>
</item>
</layer-list>
make sure to call view.getBackground().setLevel(5000) in order to see half red half green output

Shape Drawable Size not working

I have a very simple shape that I want to set the width of:
<shape android:shape="rectangle">
<solid android:color="#color/orange"/>
<size android:width="2dp"/>
</shape>
However, when I assign this to the background of a EditText it just shows an orange background instead of a rectangle of width 2dp. Why isn't setting the size working? I want to create a transparent drawable with a orange rectangle on the left side. I also have this wrapped in a selector:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true">
<shape android:shape="rectangle">
<solid android:color="#color/orange"/>
<size android:width="2dp" android:height="6dp"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#android:color/transparent"/>
</shape>
</item>
</selector>
I've tried adding height just to see if it would change the size. It doesn't. It's like its completely ignoring the size. WTF?
For me, setting the gravity of the item to "center" solved the issue.
For example:
<item android:id="#android:id/progress" android:gravity="center">
<clip>
<shape>
<size android:height="2dp"/>
<solid android:color="#color/my_color"/>
</shape>
</clip>
</item>
It can work with a foreground. It seems like you can't set a background's gravity. But you can on a foreground. I checked API 21, 23 and 24 (well, with the Studio design preview) and the following places a solid circle dot on the ImageView.
<shape android:shape="oval" xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/colorPrimary" />
<size android:height="8dp" android:width="8dp" />
</shape>
With the layout snippet
<ImageView
android:foreground="#drawable/list_new_dot"
android:foregroundGravity="right|center_vertical"
tools:src="#drawable/model_1_sm"
/>
UPDATE: While it appears to work in the layout design tool, it doesn't look the same in the emulator. UPDATE 2: Since this answer has a few votes, you might want to check what I actually used in order to show a new indicator dot:
https://gist.github.com/CapnSpellcheck/4d4638aefd085c703b9d990a21ddc1eb
Just to specify the user983447's answer - the size attribute does really mean a proportion. You should set the size for all shapes in your layer-list and it'll be used a as a proportion when scaling - like the layout_weight attribute of LinearLayout. So it's better to name it not a size but a weight
Below is a work-around how to implement top and bottom white lines without using the size attribute:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#fff" />
</shape>
</item>
<item android:top="1dp" android:bottom="1dp">
<shape>
<solid android:color="#888" />
</shape>
</item>
</layer-list>
I found the layer-list to be very devious for a first time Androider because of the following. At first glance most would think item top,bottom,right,left attributes are FROM the top,bottom,right,left. Where a value of the following:
<item android:top="10dp">
Would net you a starting point 10dp from the top of the respective container. This is not the case. Think of it as OFF OF the top,bottom,right,left. <item android:top="10dp"> will still net you a starting point 10dp OFF OF the top, but what happens when you want to set the bottom?
<item android:bottom="20dp">
This will not get you a bottom at 20dp from the TOP, rather a bottom of 20dp OFF OF the BOTTOM of the container.
So, for example with a 100dp container, if you wanted a rectangle with a top edge starting at 20dp and a bottom edge at 40dp:
<item android:top="20" android:bottom="60dp">
The size of a shape will be ignored when you use it as a background of a View. It will work when you show it via an ImageView:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF7700" />
<size android:width="20dp" android:height="20dp"/>
</shape>
In your layout XML:
<!-- will have the size of 20dp x 20dp -->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/my_shape"
/>
I had similar problem.
Documentation ( http://developer.android.com/guide/topics/resources/drawable-resource.html#Shape ) says:
<size>
The size of the shape.
(...)
Note: The shape scales to the size of the container View proportionate to the dimensions defined here, by default. When you use the shape in an ImageView, you can restrict scaling by setting the android:scaleType to "center".
If I understand correctly, it means that "size" tag is not for setting size but for setting proportions.
shape's size attribute will provide the value for drawable.getIntrinsicWidth & getIntrinsicHeight.
if the drawable's container(e.g. ImageView, TextView) has the layout param WRAP_CONTENT, then the container dimension will change if the drawable drawingState change.
but there are a bug in android framework in ImageView drawingState implementation
ImageView only update/resize its dimension by the drawable dimension on state_selected but don't on state_activated
used this.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<stroke
android:color="#color/lgray"
android:width="1dip" />
<corners
android:bottomLeftRadius="0dip"
android:bottomRightRadius="0.1dip"
android:topLeftRadius="0dip"
android:topRightRadius="0.1dip" />
<solid android:color="#color/White" />
</shape>
put this rectangle.xml to drawable.and set your view background.

android layer-list header and footer

I am trying to create a background drawable for a linearlayout that has multiple gradients.
E.g. I want to have a gradient at the top and bottom, and a solid color in the middle. So basically a header and footer.
I am trying to use a layer-list like this:
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<!--Red-->
<item>
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#ff0000" />
</shape>
</item>
<!-- Green -->
<!-- Offsets from the top and bottom -->
<item
android:top="20dp"
android:bottom="20dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#00ff00" />
</shape>
</item>
<item
android:top="80dp">
<!--Blue -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="#0000ff" />
</shape>
</item>
</layer-list>
The problem is, I am unsure of the max value of density independant pixels. For this to work, the bottom item offest would need to be (max dp value-20). I have tried to assume the max is 100, and also assume the max is 160 (from the documentation), but neither of these work.
Any ideas?

Categories

Resources