You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何制作带圆角图片的Material You风格Widget(RemoteView限制场景)

Solution for Material You Rounded Corner Widget with RemoteView Limitations

Got it, let's tackle this problem head-on—since RemoteViews lock us out of using modern components like ShapeableImageView, we need to work with the limited, supported tools to get that Google Photos-style rounded corner Material You widget. Here are two reliable, API 24+ compatible approaches:

Approach 1: Use RoundedBitmapDrawable (Simplest & AndroidX-Native)

RoundedBitmapDrawable is fully supported by RemoteViews and lets us create rounded corners directly from a bitmap, plus we can tie it to your existing appWidgetRadius dimension for consistency.

Step-by-Step Implementation:

  1. First, ensure you have AndroidX dependencies in your module-level build.gradle:
implementation "androidx.core:core-ktx:1.12.0"
implementation "androidx.appcompat:appcompat:1.6.1"
  1. In your AppWidgetProvider class, update the widget with the rounded drawable:
override fun onUpdate(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetIds: IntArray
) {
    appWidgetIds.forEach { appWidgetId ->
        val remoteViews = RemoteViews(context.packageName, R.layout.widget)
        
        // Load your target image (replace with your actual loading logic)
        val originalBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.MY_IMAGE)
        
        // Fetch your defined corner radius from dimens.xml
        val cornerRadius = context.resources.getDimension(R.dimen.rounded_corners)
        
        // Create and configure the rounded drawable
        val roundedDrawable = RoundedBitmapDrawableFactory.create(context.resources, originalBitmap)
        roundedDrawable.cornerRadius = cornerRadius
        roundedDrawable.isCircular = false
        roundedDrawable.setAntiAlias(true)
        
        // Attach the drawable to your ImageView
        remoteViews.setImageViewDrawable(R.id.widget_image, roundedDrawable)
        
        // Push updates to the widget
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    }
}

Approach 2: Manually Crop Bitmap with Canvas (Full Control)

If you need more flexibility (like non-uniform corners, though Material You uses uniform ones), you can manually generate a rounded bitmap using Canvas and Paint. This works seamlessly with RemoteViews too.

Step-by-Step Implementation:

First, add this helper function to your AppWidgetProvider or a utility class:

private fun getRoundedCornerBitmap(bitmap: Bitmap, cornerRadius: Float): Bitmap {
    val outputBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
    val canvas = Canvas(outputBitmap)
    
    val paint = Paint().apply {
        isAntiAlias = true
        xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    }
    
    val rect = Rect(0, 0, bitmap.width, bitmap.height)
    val rectF = RectF(rect)
    
    // Draw the rounded background mask
    canvas.drawRoundRect(rectF, cornerRadius, cornerRadius, paint)
    // Draw the original bitmap over the mask
    canvas.drawBitmap(bitmap, rect, rect, paint)
    
    return outputBitmap
}

Then use it in your onUpdate method:

override fun onUpdate(
    context: Context,
    appWidgetManager: AppWidgetManager,
    appWidgetIds: IntArray
) {
    appWidgetIds.forEach { appWidgetId ->
        val remoteViews = RemoteViews(context.packageName, R.layout.widget)
        
        val originalBitmap = BitmapFactory.decodeResource(context.resources, R.drawable.MY_IMAGE)
        val cornerRadius = context.resources.getDimension(R.dimen.rounded_corners)
        val roundedBitmap = getRoundedCornerBitmap(originalBitmap, cornerRadius)
        
        remoteViews.setImageViewBitmap(R.id.widget_image, roundedBitmap)
        
        appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
    }
}

Bonus: Match Material You Widget Background

To make the widget fully align with Material You styling, apply the same corner radius to your layout's background:

  1. Create res/drawable/widget_background.xml:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="?android:attr/colorBackground" />
    <corners android:radius="@dimen/rounded_corners" />
</shape>
  1. Update your widget.xml LinearLayout:
<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="@drawable/widget_background"
    android:theme="@style/widget_theme">
    <!-- Your ImageView here -->
</LinearLayout>

Quick Notes:

  • Remote Image Loading: If you're using remote images instead of drawables, use libraries like Glide (with AppWidgetTarget) or Coil (with RemoteViewsTarget)—they handle bitmap resizing and rounding safely for widgets.
  • Performance: Resize bitmaps to match your widget's actual size before applying rounding to avoid memory overhead. Use Bitmap.createScaledBitmap for this.

内容的提问来源于stack exchange,提问作者Vreny

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:53:13