In this short post I will be showing you how to achieve click effect on ShapeableImageView
which was recently released under android’s Material Components v1.2.0
If you are targeting devices running Marshmallow then you are in luck. You can use android:foreground
property to easily achieve click effect, following code snippet demonstrates the above case.
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/ivLogo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
app:srcCompat="@drawable/ic_logo" />
However if you are supporting Lollipop devices then you are out of luck since foreground is only available on api level 23. There is another way using nested views one above the other i.e. using two ShapeableImageView’s. The trick is to use a shape style and a ripple drawable configured together to achieve our goal. This hack also works for network images loaded using glide or picasso.
First let’s create a ripple drawable named ripple_effect.xml
and save it under res/drawable directory
<?xml version="1.0" encoding="UTF-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#DEFFFFFF">
<item
android:id="@android:id/mask"
android:drawable="@android:color/white" />
</ripple>
Please note the above ripple drawable uses a transluent white color with 87% alpha. This helps in achieving the required click effect
Now add the following style to the styles.xml
<style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent="">
<item name="cornerSize">50%</item>
</style>
<style name="ShapeAppearanceOverlay.App.CornerSize4dp" parent="">
<item name="cornerSize">4dp</item>
</style>
<style name="ShapeAppearanceOverlay.App.CornerSize8dp" parent="">
<item name="cornerSize">8dp</item>
</style>
As you might have probably guessed this feature was recently added in the material design components v1.2.0. This new feature helps us to easily create rounded shapes using overlay.
Only the first style is required if you want to create a image with a full circle. Other styles are shown to create a rounded image with 4 or 8 dp corners.
The final piece of this hack is to apply the above style and ripple drawable to a ShapeableImageView’s.
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="..."
xmlns:app="..."
xmlns:tools="..."
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/art"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:clickable="true"
android:focusable="true"
android:scaleType="centerCrop"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize50Percent"
tools:src="@tools:sample/avatars" />
<com.google.android.material.imageview.ShapeableImageView
android:layout_width="0dp"
android:layout_height="0dp"
android:adjustViewBounds="true"
android:background="@drawable/ripple_effect"
android:clickable="true"
android:focusable="true"
app:layout_constraintBottom_toBottomOf="@+id/art"
app:layout_constraintDimensionRatio="1:1"
app:layout_constraintEnd_toEndOf="@+id/art"
app:layout_constraintStart_toStartOf="@+id/art"
app:layout_constraintTop_toTopOf="@+id/art"
app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.App.CornerSize50Percent" />
</androidx.constraintlayout.widget.ConstraintLayout>
You can now use any popular image loading library to load a image from network.