Do you rely on external libraries to draw shapes on your ImageView
? Well now there is ShapableImageView in Android to facilitate just that.
But the best part is that you don’t need to use the circular image view libraries.
Quick Navigation
What is ShapableImageView in Android ?
ShapableImageView in Android is a subclass of ImageView that supports custom shapes. Such as circular frame or rounded corners.
Sure, you can achieve that by just wrapping the ImageView
inside a CardView
. But here we will look at using the ShapableImageView
‘s API.
It was introduced in material design library version 1.2. And it provides a rather convenient way to do things.
We will look at what shapes we can create using ShapableImageView. And we will also look at problems and their solutions using in ShapableImageView.
You must also include this library in the dependencies
// update the version if gradle suggests you to
implementation 'com.google.android.material:material:1.2.1'
Code language: JavaScript (javascript)
Styling Attributes in ShapableImageView
Before we move on let us see what do we need to style our view.
We must know that there are exactly 2 ways to do things. One is through Java/Kotlin and the other is through XML.
Here I will described about the XML way. And later we will look into the programmatic way.
Step 1: We must create a style in styles.xml
or theme.xml
.
<style name="ShapeAppearance.CircularBorder" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
Code language: HTML, XML (xml)
If we look at the snippet above. We can see the cornerFamily and cornerSize attribute.
cornerFamily
has only two values rounded and cut. And,
cornerSize takes in the dp unit like: 8dp, 20dp, etc. And the variations are cornerSizeTopLeft
, cornerSizeTopRight
, cornerSizeBottomLeft
, cornerSizeBottomRight
.
And it adjusts the roundness of each of the corners.
Now that we have understood what we need let us move on with our goal.
Circular Border for Image
Our resulting UI will look like below. Focus on the Image only.
To create a circular border add the snippet in your styles.xml
or themes.xml
. Change the percentage to see how the border changes.
<style name="ShapeAppearance.CircularBorder" parent="">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">50%</item>
</style>
Code language: HTML, XML (xml)
And add the following ShapableImageView in your layout.
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/siv"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginTop="32dp"
android:scaleType="fitCenter"
android:src="@drawable/my_bell_icon"
app:shapeAppearanceOverlay="@style/ShapeAppearance.CircularBorder"
app:strokeColor="@color/colorPrimaryDark"
app:strokeWidth="2dp" />
Code language: HTML, XML (xml)
From the code snippet about we can see these attributes stand out
app:shapeAppearanceOverlay
is how we change the shape. So, in our case it is@style/ShapeAppearance.CircularBorder
.app:strokeColor
is for adding the border color. And,app:strokeWidth
is for the width of the border.
Now there is a problem with our output, the image has no space with the border. We will look at this later on in the post.
Diamond Cut Border for Image
The output of cut corner style is shown below
Just like in the style above we have to declare the style with cornerFamily cut.
<style name="ShapeAppearance.CutBorder" parent="">
<item name="cornerFamily">cut</item>
<item name="cornerSize">50%</item>
</style>
Code language: HTML, XML (xml)
- 50% will produce a diamond like shape.
- 25% will produce a octagonal shape.
And the code for our layout will stay same except for the name of app:shapeAppearanceOverlay.
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/siv"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginTop="32dp"
android:scaleType="fitCenter"
android:src="@drawable/my_bell_icon"
app:shapeAppearanceOverlay="@style/ShapeAppearance.CutBorder"
app:strokeColor="@color/colorPrimaryDark"
app:strokeWidth="2dp" />
Code language: HTML, XML (xml)
Now we have completed the basic styling for our ShapableImageView. Let us look at the main problem in each of the example above.
Padding issue with ShapableImageView
If we see closely with the image above we can see that there is no space between the border and the image. This can look really not clean in certain situations.
Let us try adding the padding attribute to the ShapableImageView to solve this.
After adding the output is exactly same except the image has reduced in size. So, clearly setting padding to the layout doesn’t solve the issue.
Whats the solution then ?
Well it’s pretty easy, we have to create a custom inset drawable. Create a new resource file in the drawable directory.
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_bell"
android:inset="8dp" />
Code language: HTML, XML (xml)
android:drawable
is where you actual image will be referenced- android:inset is just like android:padding put in a dp value
After creating the new drawable resource. We have to use it instead of the actual image like below
android:src="@drawable/inset_draw"
Code language: JavaScript (javascript)
Which was before
android:src="@drawable/my_bell_icon"
Code language: JavaScript (javascript)
And the out put of the adjustments is like below.
It’s almost perfect but there’s still a little problem. Can you see it ?
Cutting Side Issue in ShapableImageView Android
If you look closely you can see the ShapableImageView has a bit of our border cut off at each side.
Let us solve that issue too. It’s really simple. We just have to use the padding in our layout. And the value must be half of app:strokeWidth
.
In the above examples we can see we have 2dp width of stroke. So let us include padding of 1dp in our layout.
As you can see the issue is now gone. If it doesn’t resolve you can try increasing the padding with practical units.
Why did the cut happen ? It’s in the way the ImageView draws the mentioned drawable.
I hope you liked the implementation, be sure to bookmark and visit often for new tutorials.
Related Posts
– Android Content URI: How to Get the File URI
– Show or Hide Soft Keyboard in Android Application And More
– Android Notification Manager: Create Notification in Android
– Android Room For Database: Learn SQLite Persistence Library