Featured image of post How to achieve click effect on ShapeableImageView

How to achieve click effect on ShapeableImageView

Click effect without using android's foreground property

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.

Photo by Elly Brian on Unsplash
comments powered by Disqus
Jai Jeendra
Built with Hugo
Theme Stack designed by Jimmy