How to force android:shape="oval" to remain perfect circle? - android

I am trying to define a circular background to be used as a background for buttons.
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetLeft="#dimen/abc_button_inset_horizontal_material"
android:insetTop="#dimen/abc_button_inset_vertical_material"
android:insetRight="#dimen/abc_button_inset_horizontal_material"
android:insetBottom="#dimen/abc_button_inset_vertical_material">
<shape android:shape="oval">
<solid android:color="#color/material_orange_200" />
<padding android:left="#dimen/abc_button_padding_horizontal_material"
android:top="#dimen/abc_button_padding_vertical_material"
android:right="#dimen/abc_button_padding_horizontal_material"
android:bottom="#dimen/abc_button_padding_vertical_material" />
</shape>
</inset>
The problem is that if the button is not completely square the shape get stretched into oval (elipsoid) which is undesirable. I could use <size> tag and set width and height to the same arbitrary value. But this would defeat the purpose to use this background as universal background for different size buttons.
Is there a way to force (in xml) oval shape to remain a circle?

create a drawable file like this
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid android:color="#22C2FE" />
<stroke
android:width="0dp"
android:color="#2B8DC6"></stroke>
</shape>
and use the same height and width on which view are using the drawable.

Related

How can I add image from src attribute to gradient.xml file in Android?

I am new to Android and I want to display image with gradient background. Is it possible to add an image into gradient.xml?
Below is the xml code for this.
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="#drawable/bg"/>
<shape>
<gradient
android:startColor="#631f68"
android:endColor="#ff5555"
android:angle="45"/>
</shape>
</item>
Solution:
In your main_activity.xml,
set the background image for your topmost layout: (Relative or Constraint whatever you are using)
Then take another layout and give height and width to match_parent and apply the below Gradient to the background of it.
Gradient file:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="135"
android:centerColor="#color/colorAccentSecondary"
android:endColor="#color/colorPrimary"
android:startColor="#color/colorAccent"
android:type="linear" />
<corners android:radius="0dp" />
</shape>
Hope it helps.

Android enlarge center color with gradient

I can not enlarge the width of a centeral color with a gradient.
The goal is:
Larger center with some color, and transparent on sides.
Usage:
<ImageView
android:layout_width="match_parent"
android:layout_height="5dp"
android:src="#drawable/gradient_normal"/>
I tried many combinations with layer-list, but the result was not nice. One solution can be divide Layout to 50%-50% and set the first gradient from left to right (from transparent to color) and second right to left (from color to transparent), but this solution seems very complicated to me.
For example, this generator cannot enlarge the center yellow color. (There is Android XML code generator.)
Any simpler solution? Thank you.
API21+
I hope this is what you had in mind. I am using layer-list. I have used "#color/colorAccent" for either end. Change it to "#0FFF" to get a transparent color, which was required in the question.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="50dp">
<shape android:shape="rectangle">
<gradient
android:startColor="#color/colorPrimary"
android:endColor="#color/colorAccent"
android:centerColor="#color/colorPrimary"
android:centerX="10%"/>
<size
android:height="100dp"
android:width="50dp"/>
</shape>
</item>
<item
android:right="50dp">
<shape android:shape="rectangle">
<gradient
android:startColor="#color/colorAccent"
android:endColor="#color/colorPrimary"
android:centerColor="#color/colorPrimary"
android:centerX="80%"/>
<size
android:height="100dp"
android:width="50dp"/>
</shape>
</item>
</layer-list>
Play around with the android:centerX attributes till you get what you want.
OUTPUT
This is what the drawable preview looks like with centerX at 10% and 80%
now with centerX at 60% and 40%
EDIT
To get the same effect in a layout that uses match_parent as the layout_width parameter, split the gradient into two drawables and set it as background for 2 different ImageViews or FrameLayouts
left_gradient.xml
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#0FFF"
android:centerColor="#000"
android:centerX="50%"
android:endColor="#000"/>
</shape>
right_gradient.xml
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#000"
android:centerColor="#000"
android:centerX="50%"
android:endColor="#0FFF"/>
</shape>
In your Layout xml file
<LinearLayout
android:layout_width="match_parent"
android:layout_height="15dp"
android:baselineAligned="false">
<FrameLayout
android:layout_width="0dp"
android:background="#drawable/left_gradient"
android:layout_height="match_parent"
android:layout_weight="1"/>
<FrameLayout
android:layout_width="0dp"
android:background="#drawable/right_gradient"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
Like with the previous case, tweak around with the values in android:centerX of both the gradient files to get the desired result
For someone who is still searching for answer...
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="90"
android:centerColor="#android:color/transparent"
android:centerY="0.8"
android:endColor="#60000000"
android:startColor="#android:color/transparent" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="90"
android:centerColor="#android:color/transparent"
android:centerY="0.2"
android:endColor="#android:color/transparent"
android:startColor="#60000000" />
</shape>
</item>
</layer-list>

Tile with a drawable background exceeds height limit

I made a tile with some "shadow" and rounded corners using the following layer-list:
<?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" />
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="#color/activity_background" />
<corners android:radius="5dp" />
</shape>
</item>
<item android:bottom="3px" android:right="3px">
<shape android:shape="rectangle">
<solid android:color="#color/header" />
</shape>
</item>
</layer-list>
It's used as a background for dynamically loaded views that are not activity layouts, and thus do not cover the whole screen (notifications, for example).
Here's a layout that uses this tile:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="70dp"
android:padding="6dp"
android:background="#drawable/tile">
...
</RelativeLayout>
Now I want to use a drawable PNG as the background of the layout. I tried to put it directly as the background of the layout android:background="#drawable/blob_gradient" but then the first view (aka first notification) covers the whole screen. I also tried to use the tile with android:drawable="#drawable/blob_gradient" in its last item, but same results.
I'm sure that the solution is simple, and I probably approach the subject with the wrong attitude. Any help will be appreciated.

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>

How to alter LayerDrawable within ImageView?

I'm adding a couple of ImageView to a LinearLayout programmatically, those ImageView have its src set to R.drawable.rectangle.
I'm trying to create a rectangle with solid color that has a border only to the left.
R.drawable.rectangle looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="#000000" />
<stroke android:width="1dp" android:color="#999" />
</shape>
</item>
<item
android:top="0dp" android:left="1dp" android:bottom="0dp" android:right="0dp">
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#283BCB"/>
<size android:width="100dp" android:height="8dp" />
</shape>
</item>
</layer-list>
In my activity, I'm inflating the layout that contains the LinearLayout and I'm adding ImageViews to it programatically, that is all working. The problem is that I don't manage to manipulate the rectangle width. If I do:
imageView.getLayoutParams().width = 10;
Rectangles need to be different sizes and colors. However if I do it this way, rectangles get deformed weirdly, this doesn't happen If I don't use a layer-list, but only a shape (but that way I cannot add a left border).
So I'm guessing I need to get LayerDrawable, then get GradientDrawable and change it. However I'm not having any luck achieving this.
LayerDrawable layer = (LayerDrawable)imageView.getDrawable();
GradientDrawable rectangle = (GradientDrawable)layer.getDrawable(1);
// rectangle.setBounds
// rectangle.setColor NOT working
Any hints? thanks

Categories

Resources