'Widget that contains image with rounded corners

How to make a Material You-like widget with image whose corners are rounded?

It is already made in Google Photo, but how to get the same effect?

Many ways (like ShapeableImageView) are forbidden and impossible to bypass due to restrictions of RemoteView.

These are some additional details for the first suggested answer:

My widget.xml looks like this:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/colorBackground"
    android:theme="@style/widget_theme">

    <ImageView
        android:id="@+id/widget_image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/MY_IMAGE" />

</LinearLayout>

attrs.xml in res/values folder looks like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="AppWidgetAttrs">
        <attr name="appWidgetPadding" format="dimension" />
        <attr name="appWidgetInnerRadius" format="dimension" />
        <attr name="appWidgetRadius" format="dimension" />
    </declare-styleable>
</resources>

styles.xml in res/values folder looks like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- Widget theme -->
    <style name="widget_theme" parent="Theme.Material3.DayNight">
        <item name="appWidgetRadius">@dimen/rounded_corners</item>
        <item name="appWidgetInnerRadius">@dimen/rounded_corners_inner</item>
        <item name="appWidgetPadding">0dp</item>
    </style>

</resources>

dimens.xml in res/values folder looks like this:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="rounded_corners">16dp</dimen>
    <dimen name="rounded_corners_inner">8dp</dimen>
</resources>

I test my app on a virtual Pixel 4a (API 30).

Minumum API is API 24.

Compile and Target SDKs are both API 31.



Solution 1:[1]

Actual solution

What the op wants is a widget containing only an image, and this image should be rounded, example:

Rounded corners image in widget

All you need is:

  • the widget layout, containing an imageview with your image. In the above example, i had (i used linear layout, but it depends on the desired final result):
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/background"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/colorBackground"
    android:theme="@style/WidgetTheme">

    <ImageView
        android:id="@+id/test"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@drawable/test" />

</LinearLayout>
  • A style for your widget, that's mine (supports the rounded corners and the automatic dark/light theme, even if in this particular widget the background color is not visibile)
    <!-- Widget theme -->
    <style name="WidgetTheme" parent="Theme.Material3.DayNight">
        <item name="appWidgetRadius">@dimen/rounded_corners</item>
        <item name="appWidgetInnerRadius">@dimen/rounded_corners_inner</item>
        <item name="appWidgetPadding">0dp</item>
    </style>
  • The above attributes must be declared as styleable in the attrs.xml file. Again, here's mine:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="AppWidgetAttrs">
        <attr name="appWidgetPadding" format="dimension" />
        <attr name="appWidgetInnerRadius" format="dimension" />
        <attr name="appWidgetRadius" format="dimension" />
    </declare-styleable>
</resources>

That's all, if you want the image to be circular just set a huge border radius.

Old and misunderstood solution

I'm probably late, but i had the same problem. A simple workaround is to use a foreground to "mask" tha image form, when the image is a normal ImageView inside the widget's layout. So what i did was:

  1. Create this drawable, name it as you want
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="24dp"
        android:height="24dp"
        android:viewportWidth="24"
        android:viewportHeight="24">
      <path
          android:pathData="M-0.1094,-0.0957L-0.1094,24.0957L24.1094,24.0957L24.1094,-0.0957L-0.1094,-0.0957zM12,0.123A11.8773,11.8773 0,0 1,23.877 12A11.8773,11.8773 0,0 1,12 23.877A11.8773,11.8773 0,0 1,0.123 12A11.8773,11.8773 0,0 1,12 0.123z"
          android:fillColor="#000"/>
    </vector>
  1. Use this drawable in your ImageView foreground and set its color to the background color (here i use the system background color, but use your color if it's different):
android:foreground="@drawable/ic_inverted_circle_foreground_black_24dp"
android:foregroundTint="?android:attr/colorBackground"
  1. Result:

Square image with inverse circle foreground

EDIT: the op request was different, but this remains a valid solution for images inside the layout of the widget, so i won't delete it, just in case.

Sources

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

Source: Stack Overflow

Solution Source
Solution 1