'How to achieve click effect on ShapeableImageView, min api 21 without nesting view

Is there a better way to achieve click effect on ShapeableImageView with recent release of Material components v1.2.0

I do not want to use foreground property as it is available after api level 23 and my current min sdk level is 21.
eg android:foreground="?selectableItemBackground"

The only solution currently that I have is to nest a view on top of ImageView, but this seems to be bad solution as just to get a click I have to add a nested view on top of it.

Also I would consider to do it purely using XML and no coding as I have many layouts with ImageView grids.

There are similar questions on SO already asked for ImageView and AppCompatImageView but those are either legacy solutions, target api level 23 using foreground or third party lib.

Below is my layout which will be used inside a RecyclerView as a grid item

<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>

Below is the style to make ImageView into full circle

<!-- CornerSize50Percent -->
<style name="ShapeAppearanceOverlay.App.CornerSize50Percent" parent="">
    <item name="cornerSize">50%</item>
</style>

Below is the ripple effect drawable

<!-- ripple_effect -->
<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>

Link to issue on github



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source