I am trying to create a chat bubble design with android drawables
My design idea was the following:
What I currently have, but what I don't like is that:
The code is the following:
<layer-list>
<item
android:right="1dp"
android:top="12dp">
<rotate
android:fromDegrees="45"
android:pivotX="100%"
android:pivotY="0%"
android:toDegrees="0">
<shape android:shape="rectangle">
<solid android:color="?attr/message_out_color" />
<stroke
android:width="1px"
android:color="#color/colorFakeShadow" />
</shape>
</rotate>
</item>
<item
android:right="8dp"
android:top="1dp">
<shape android:shape="rectangle">
<solid android:color="?attr/message_out_color" />
</shape>
</item>
</layer-list>
I tried to use the corner tag with a high radius, but that didn't result in what I imagined. Another idea was to use two ovals as that is how I've done my design idea in Paint.NET, but I didn't manage to position the ovals right. Is my idea possible to create with android drawables and if so how?
UPDATE: When I add <corners android:radius="50dp" /> it looks like this
But as you can see, it is too round, it doesn't look like my image (the first one in this post).
UPDATE 2: I cannot use 9 patch drawables, because these message bubbles have to scale in all directions, and also I need a <ripple> on the shape because the user can click on my message bubble, which can't be done with a 9 patch.
Thanks in advance!
Related
I am not sure what to call this... pill shaped maybe. Googling for rounded corners turns up lots of posts of people wanting a rectangular button with rounded corners. This is a little different but more like 2 circles and a rectangle which I tried to draw it as.
I would like to make a button shaped something like the first image below but with text and an icon image in it by using an xml drawable background on an android :
I have tried this which looks ok but if the button length varies it does not scale and you end up with a rectangle and some other strange stuff.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:left="40dp" android:top="0dp" android:bottom="0dp">
<shape android:shape="oval" >
<solid android:color="#666666"/>
<size android:width="40dp" android:height="40dp"></size>
</shape>
</item>
<item android:left="20dp" android:right="20dp">
<shape android:shape="rectangle" >
<solid android:color="#666666"/>
<size android:width="20dp" android:height="20dp"></size>
</shape>
</item>
<item android:right="40dp">
<shape android:shape="oval" >
<solid android:color="#666666"/>
<size android:width="40dp" android:height="40dp"></size>
</shape>
</item>
</layer-list>
I have tried to create my xml drawable like this also:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#666666" />
<corners android:radius="20dp"/>
<size android:height="20dp" android:width="60dp"></size>
</shape>
which looks like this:
I have looked at this persons example but when I do what he does my results are not completely rounded at the corners. They are more like the second image above.
You can try to save the following code to a drawable(e.g. pill_bg.xml):
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:shape="rectangle">
<corners android:radius="120dp" />
<solid android:color="#color/white" />
<stroke
android:width="1dp"
android:color="#efefef" />
<size
android:width="300dp"
android:height="120dp" />
</shape>
Take a look at size part and radius. Then apply the drawable to your view, for example:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="250dp"
android:layout_height="60dp"
android:background="#drawable/pill_bg" />
As you can see, your view can have different sizes, the background will be scaled.
As of v1.1.0-beta01 of the Material Components Android library you can use MaterialButton and a shapeAppearance style to easily define a pill button that doesn't require you to know the height of the button beforehand or rely on guessing a radius value high enough to go halfway down the side of the button.
Simply define a style like this:
<style name="PillShapeAppearance">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
and set it on your MaterialButton like this:
<com.google.android.material.button.MaterialButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
app:shapeAppearanceOverlay="#style/PillShapeAppearance"
/>
The key that every other answer I've looked at leaves out is to set cornerSize with a percent value so that the fraction value it supports is properly applied.
This resizes correctly for any view background.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="1000dp" />
<solid android:color="#android:color/holo_red_dark" />
</shape>
Well you can make that button in any design program, also make one similar make it look like it is pressed then you make a selector drawable and assign it to the button background. That´s the way i do pretty awesome buttons
I've created a button, when it's clicked, it's like the picture below.
For now, it's an image created with Gimp and 9-patch. It works, but I want to know if there is a way to create the same image with a Shape in XML (only the blue part in the middle). So in the future, I can change for example the color very easily.
Thanks in advance.
Edit :
I tried something :
<item >
<shape android:shape="rectangle">
<solid android:color="#color/blue1"/>
</shape>
</item>
<item>
<rotate
android:fromDegrees="45"
android:toDegrees="45"
android:pivotX="-40%"
android:pivotY="87%" >
<shape
android:shape="rectangle" >
<solid
android:color="#android:color/transparent" />
</shape>
</rotate>
</item>
But, of course, it doesn't work. The transparent triangle just show the blue rectangle in the background. Maybe with two triangle and one square, but i'm really weak in android shape system.
In my application, I'm (still) trying to manipulate my Button Views to look the way I want. I'd like to attempt an experiment where I'll draw an Android Rect or RectF in the same location as the (transparent) button to highlight it's appearance.
However, I can't figure out how to get my mitts on that information. The buttons in question are defined in XML, in a Linear Layout, but something inside my Android has to know their sizes and locations. Right?
Any suggestions?
Thanks, R.
You should be able to set a background of the button to a custom xml drawable with the drawable containing only stroke element around the edge.
You will need to create this custom drawable: it would be just a few lines of XML.
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="1dp" android:color="#CCCCCC" />
<corners android:radius="10dp" />
</shape>
Edit: updated to include rounded corners.
This answer is a combination of my poking around and Aleks' suggestion to use a custom drawable. Ultimately, my custom drawable needed more than three lines, but it's still not very big:
<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:startColor="#android:color/black"
android:endColor="#android:color/black" />
<stroke
android:width="1dp"
android:color="#cccccc" />
<corners
android:radius="5dp" />
<padding
android:left="4dp"
android:top="2dp"
android:right="4dp"
android:bottom="2dp" />
</shape>
</item>
</selector>
I needed to add all of the other detail to get the custom button to work the way I wanted -- and I'm probably not done, but if anybody is interested, this works pretty well...
I need to implement such button for my Android app. It would be great to do this without using full image as button.
I've done almost the same button using <shape> with <gradient>. The only thing I need is to add bottom blue button shadow and include image.
Is it possible?
Thanks in advance.
You can do this by combining Shape Drawables inside a Layered Drawable. To do so, you'll have 3 xml files as below:
button.xml (the one you already have i guess)
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="16dp" />
<gradient
android:angle="270"
android:centerColor="#FFFFFF"
android:endColor="#CAEBF8"
android:startColor="#FFFFFF"
android:type="linear" />
<padding
android:bottom="8dp"
android:left="8dp"
android:right="8dp"
android:top="8dp" />
<stroke
android:width="2dp"
android:color="#FFFFFF" />
</shape>
button_bg.xml (to add the blue border below the button)
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<corners android:radius="16dp" />
<solid android:color="#6FC8F1" />
</shape>
layered_button.xml (to combine the previous xml, and the drawable to use as background on your button)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:drawable="#drawable/button_bg"/>
<item
android:bottom="2dp"
android:drawable="#drawable/button"/>
</layer-list>
You'll find more information on the Layer List in the Drawables Documentation
Make your button's android:background attribute to point your desired image. Create your image with the text and the little person icon. It's not possible to put a text and an image at the same time inside a button.
For the blue shadow, you can either include it in your image or achieve the same result with the gradient attribute as you already said in your question.
For the image, you should use
android:drawableRight
As for the shadow I'm not sure how this is achieved.
I want to make a shape with with left-top rounded corner and left-bottom rounded corner:
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#555555"/>
<stroke android:width="3dp"
android:color="#555555"
/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
/>
<corners android:bottomRightRadius="0dp" android:bottomLeftRadius="2dp"
android:topLeftRadius="2dp" android:topRightRadius="0dp"/>
</shape>
But the shape above didn't give me what I want. It gives me a rectangle without any rounded corners.
It looks like a bug http://code.google.com/p/android/issues/detail?id=939.
Finally I have to write something like this:
<stroke android:width="3dp"
android:color="#555555"
/>
<padding android:left="1dp"
android:top="1dp"
android:right="1dp"
android:bottom="1dp"
/>
<corners android:radius="1dp"
android:bottomRightRadius="2dp" android:bottomLeftRadius="0dp"
android:topLeftRadius="2dp" android:topRightRadius="0dp"/>
I have to specify android:bottomRightRadius="2dp" for left-bottom rounded corner (another bug here).
While this question has been answered already (it's a bug that causes bottomLeftRadius and bottomRightRadius to be reversed), the bug has been fixed in android 3.1 (api level 12 - tested on the emulator).
So to make sure your drawables look correct on all platforms, you should put "corrected" versions of the drawables (i.e. where bottom left/right radii are actually correct in the xml) in the res/drawable-v12 folder of your app. This way all devices using an android version >= 12 will use the correct drawable files, while devices using older versions of android will use the "workaround" drawables that are located in the res/drawables folder.
From the documentation:
NOTE: Every corner must (initially) be provided a corner radius greater than 1, or else no corners are rounded. If you want specific
corners to not be rounded, a work-around is to use android:radius to
set a default corner radius greater than 1, but then override each and
every corner with the values you really want, providing zero ("0dp")
where you don't want rounded corners.
E.g. you have to set an android:radius="<bigger than 1dp>" to be able to do what you want:
<corners
android:radius="2dp"
android:bottomRightRadius="0dp"
android:topRightRadius="0dp"/>
You can also use extremely small numbers for your radius'.
<corners
android:bottomRightRadius="0.1dp" android:bottomLeftRadius="2dp"
android:topLeftRadius="2dp" android:topRightRadius="0.1dp" />
for others there are a solution for any API level , you can place a item on top of each other example :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- my firt item with 4 corners radius(8dp)
-->
<item>
<shape>
<solid
android:angle="270.0"
android:color="#3D689A" />
<corners android:topLeftRadius="8dp" />
</shape>
</item>
<!-- my second item is on top right for a fake corner radius(0dp)
-->
<item
android:bottom="30dp"
android:left="50dp">
<shape>
<solid android:color="#5C83AF" />
</shape>
</item>
<!-- my third item is on bottom left for a fake corner radius(0dp)
-->
<item
android:right="50dp"
android:top="30dp">
<shape>
<solid android:color="#5C83AF" />
</shape>
</item>
</layer-list>
the result with light color to show you the three items :
the final result :
Best regards.
This bug is filed here.
This is a bug of android devices having API level less than 12.
You've to put correct versions of your layouts in drawable-v12 folder which will be used for API level 12 or higher.
And an erroneous version(corners switched/reversed) of the same layout will be put in the default drawable folder which will be used by the devices having API level less than 12.
For example: I had to design a button with rounded corner at bottom-right.
In 'drawable' folder - button.xml: I had to make bottom-left corner rounded.
<shape>
<corners android:bottomLeftRadius="15dp"/>
</shape>
In 'drawable-v12' folder - button.xml: Correct version of the layout was placed here to be used for API level 12 or higher.
<shape>
<corners android:bottomLeftRadius="15dp"/>
</shape>
try this
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/upkia"/>
<corners android:radius="10dp"
android:topRightRadius="0dp"
android:bottomRightRadius="0dp" />
</shape>
This works for me
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#color/colorPrimary" />
<corners
android:bottomLeftRadius="0dp"
android:radius="#dimen/dimen_5dp"
android:topLeftRadius="0dp" />
</shape>