I have a circular ImageView as you can see below, this references a vector drawable, I would like to fill the inside of the circle with another View, without having that rectangle outside the circle, is this possible in any way?
<FrameLayout
android:layout_gravity="center_horizontal"
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#android:color/black"
>
<com.myapp.MySpecialBackground
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/icon"
android:tint="#color/blue"/>
</FrameLayout>
You can use a ShapeDrawable as background resource. Add a drawable resource file to your project and set the "padding" so the circular shape will not show outside of your blue circle:
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<padding
android:left="30dp"
android:top="30dp"
android:right="30dp"
android:bottom="30dp" />
<size
android:width="150dp"
android:height="150dp" />
<solid android:color="#ff0000"/>
</shape>
I used 30dp but that's hard to tell from your screenshot, so most likely you'll have to experiment. Just keep in mind that you'll get a circle if your ImageView is a square and all padding values are equal.
(For older android versions: the size tag is relatively new, in earlier versions the width and height attributes went into the shape tag)
Related
I have a text view and and I want its background to be a image and also its corners rounded. I have tried that by creating a drawable file but the background image gets spilled out.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="200dp"
android:padding="5dp"
android:orientation="horizontal">
<TextView
android:id="#+id/info_text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textColor="#color/colorPrimaryDark"
android:background="#drawable/drawable_file"
/>
</LinearLayout>
drawable_file.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:src="#drawable/img" />
</item>
<item>
<shape>
<stroke
android:width="1dp" />
<corners android:radius="50dp" />
</shape>
</item>
</layer-list>
Output:
Example Output:
As in official Android documentation for LayerList
A LayerDrawable is a drawable object that manages an array of other drawables. Each drawable in the list is drawn in the order of the list—the last drawable in the list is drawn on top.
Meaning your drawable needs to be placed after the rounded background to be visible.
I have a View with a background of a circle drawable. I want the circle to be larger than it's containing view, but still clipped off. The problem is, the drawable size doesn't want to go beyond the view's size, and the whole circle is much smaller than I need it to be.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp">
<View
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentRight="true"
android:background="#drawable/circle" />
</RelativeLayout>
And the circle.xml:
<shape android:shape="oval">
<solid android:color="#ff0000" />
</shape>
How can I get the get the large cropped circle instead?
<shape android:shape="oval">
<size android:width="50dp" android:height="50dp" />
<solid android:color="#ff0000" />
</shape>
If problem still exists, you may need to use ImageView and setImageResource instead of view and backgrounds.
Make sure you set android:clipChildren="false" atribute in the view parent and its parent.
I have a linearlayout background set to a drawable file in order to create that rounded corner look as such:
<LinearLayout
android:id="#+id/layout_top"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#drawable/rectangle_topcorner">
<TextView android:layout_width="fill_parent"
android:id="#+id/textView1"
android:layout_height="wrap_content"
android:text="Impact"
android:layout_gravity="center"
android:textColor="#android:color/white"
android:layout_marginLeft="10dip" />
</LinearLayout>
In my adapter, after I inflate the layout item, I am trying to change the backgroundColor to a 'different' drawable, in order to change the background color:
LinearLayout top = (LinearLayout) view.findViewById(R.id.layout_top);
top.setBackgroundColor(R.drawable.rectangle_topcorner_high);
The problem is, after doing that, the rectangle loses its rounded corner look and its just a plain old square.
The 2 drawables:
rectangle_topcorner
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:id="#+id/background_shape" >
<corners android:topLeftRadius="30dp"
android:topRightRadius="30dp" />
<solid android:color="#005577"/>
</shape>
rectangle_topcorner_high
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle"
android:id="#+id/background_shape" >
<corners android:topLeftRadius="30dp"
android:topRightRadius="30dp" />
<solid android:color="#83162D"/>
</shape>
I'm missing something to preserve the rounded corners ?
Try using:
top.setBackgroundResource(R.drawable.rectangle_topcorner_high);
setBackgroundColor are for color resources
Thought I would share my eventual fix -
As I was trying variants of
top.setBackgroundColor(R.drawable.rectangle_topcorner_high);
The correct (working) code is:
top.setBackground(context.getResources().getDrawable(R.drawable.rectangle_topcorner_high));
I'm trying to simplify some graphics from requiring a 9-patch for each density, to just using an XML drawable. It's a fairly simple graphic:
2 Segments:
8dp wide for both segments
Top segment is 2dp tall
Bottom segment fills the view
Right side is filled with transparency
Giving this result when set as a background image:
It seems like this should be fairly simple to recreate as an XML drawable, and would avoid creating 5 different 9-patch graphics. However, I've looked into layer-list drawables, inset drawables, clip drawables -- they all seem to require that you know the size of the view beforehand (e.g. to keep it 2dp for an inset, you'd need to set insetRight to the width of the view - 2dp). I also tried using the shape tag's size tag, but that doesn't keep a fixed size, just a fixed proportion (so for taller views it will scale proportionally).
Am I overlooking something simple, or is this something I'd have to resort to checking programatically after layout?
This is not possible. This is the best solution I found. Only xml, no coding, no bitmaps, no additional views )
<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="#ff0000" />
</shape>
</item>
<item
android:top="4dp">
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid
android:color="#00ff00" />
</shape>
</item>
<item
android:left="10dp">
<shape
android:shape="rectangle">
<solid
android:color="#FFFFFF" />
</shape>
</item>
</layer-list>
Via code you can make your own drawble type with desired behavior. Xml drawable very limited. IMHO my suggestion is the closest to what you demanded.
I think the answer by #Leonidos is very close to what I'm proposing, except I'm using the drawable as a separate view instead of the background for the entire list detail layout. This allows it to be a fixed width and to let the item text have its own background. Let me know if I'm not understanding your constraints.
The following file is "res/drawable/list_left_border"
<?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="#e76e63" />
</shape>
</item>
<item android:top="2dp">
<shape android:shape="rectangle" >
<solid android:color="#ffc257" />
</shape>
</item>
</layer-list>
Then on the layout for the list item in "res/layout/list_item.xml"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
tools:context=".MainActivity" >
<View
android:background="#drawable/list_left_border"
android:layout_width="8dp"
android:layout_height="match_parent" />
<TextView
android:id="#+id/listItemText"
android:textSize="15sp"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
Here's the image. The background is pink to show that the list item is transparent.
I'm going to go one further and suggest a slight reworking of AndroidGuy's answer, which itself includes Leonidos' answer.
Same drawable XML, different list item XML as follows:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="100sp">
<ImageView
android:layout_width="8dp"
android:layout_height="match_parent"
android:src="#drawable/list_left_border" />
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Item Text"
android:textSize="22sp" >
</TextView>
</FrameLayout>
The FrameLayout gives the original background behaviour, rather than separation into a new view.
I've shown this below, with backgrounds to demonstrate:
This doesn't really deserve the points though.
I am trying to put two oval drawables on top of each other, the first has transparency. However with the way I have it, it displays the first oval's color at the size of the second oval.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="oval">
<size android:width="15dp" android:height="15dp" />
<solid android:color="#35000000"/>
</shape>
</item>
<item>
<shape android:shape="oval">
<size android:width="5dp" android:height="5dp" />
<solid android:color="#000000"/>
</shape>
</item>
</layer-list>
How can I get this to work as intended?
EDIT:
Here is the parent:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/my_layerlist" />
</LinearLayout>
After doing much research on the different types of XML drawables, it appears that your LayerDrawable (layer-list) is be scaling the ShapeDrawables independently. Then, the ImageView is scaling the LayerDrawable. According to this guide from Google, scaling for both ShapeDrawables and LayerDrawables is a concern. LayerDrawables will check for necessary scaling on each item you have. They have several solutions:
Set the gravity to something that does not scale, such as "center".
define the drawable as a bitmap.
Set the ImageView to scaleType that does not scale.
There is two major problem with this, however... You can only use gravity for the bitmap. And you cannot use a ShapeDrawable for the bitmap in XML. I tried everything I could think of to get it right. Here's the only thing that fixed it for me.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/imageView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/oval1"
android:scaleType="center" />
<ImageView
android:id="#+id/imageView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/oval2"
android:scaleType="center" />
</FrameLayout>
So: I removed the LayerDrawable, separated the Shapes into their own XMLs, made two ImageViews. (for ease I stuck them in a FrameLayout). This was the only way to stop the scaling.
Testing Procedure
Tested in Android 2.1, 3.0, 4.0
Changed Image scaleType
Changed Image width and height
Separated ShapeDrawables
Changed LayerList to just items with drawable attribute referencing separated shapes
Changed LayerList to bitmaps referencing separated shapes.
Changed order of shapes
Alternatively, you could do it in code.
Reference: Drawable Resources