0
0

Microsoft Launcherに設置したウィジェットに通知されるサイズが表示サイズと一致しない

Posted at

ウィジェットの検証をしていて、Microsoft Launcehrに配置したウィジェットは破綻するほどではないものの、微妙にサイズにずれが発生していることに気づきました。

検証用に以下のウィジェットを配置してみます。

class MyWidget : GlanceAppWidget() {
    override val sizeMode = SizeMode.Exact
    private val colors = listOf(Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Magenta, Color.Cyan)
    override suspend fun provideGlance(context: Context, id: GlanceId) {
        val manager = GlanceAppWidgetManager(context)
        val appWidgetId = manager.getAppWidgetId(id)
        val color = colors[appWidgetId % colors.size]
        provideContent {
            Compat {
                val density = LocalContext.current.resources.displayMetrics.density
                val size = LocalCompatSize.current
                Box(
                    modifier = GlanceModifier.background(color)
                        .fillMaxSize()
                        .appWidgetBackground(),
                    contentAlignment = Alignment.Center,
                ) {
                    Box(
                        modifier = GlanceModifier.size(size.width * 3 / 4, size.height * 3 / 4)
                            .background(GlanceTheme.colors.secondaryContainer),
                        contentAlignment = Alignment.Center,
                    ) {
                        Text(
                            text = "${(size.width.value * density).toInt()} x ${(size.height.value * density).toInt()}",
                            modifier = GlanceModifier.size(size.width / 2, size.height / 2)
                                .background(GlanceTheme.colors.widgetBackground)
                        )
                    }
                }
            }
        }
    }
}

588x484と表示されていますが、実際のピクセル数を図ってみると、588x420と横幅はあっているものの、高さが実際より大きく通知されていますね。

画面を強制的に横に倒すと、

1088x216ですが、はかってみると1035x198ですね。

Receicerで通知されるサイズを調べて見ましょう。

override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int, newOptions: Bundle) {
    super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions)
    val sizes = BundleCompat.getParcelableArrayList(newOptions, AppWidgetManager.OPTION_APPWIDGET_SIZES, SizeF::class.java)
    val minWidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, 0)
    val maxWidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH, 0)
    val minHeight = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, 0)
    val maxHeight = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT, 0)
    sizes?.forEach {
        Log.e("MyReceiver", "Sizes $appWidgetId Size: ${it.width} x ${it.height}")
    }
    Log.e("MyReceiver", "Sizes $appWidgetId P: $minWidth x $maxHeight L: $maxWidth x $minHeight")
}

結果は以下のようになっていました。

Sizes 201 Size: 224.0 x 184.38095
Sizes 201 P: 224 x 184 L: 224 x 184

OPTION_APPWIDGET_SIZESには一つだけサイズが入っていて、OPTION_APPWIDGET_XXX_XXXXにはmin/maxで同じ値が入っていますね。
一つだけというのは画面回転を想定していないのかなとは思いますが、表示されているサイズと微妙に、かつ想定外の方向にずれているので解せない挙動です。
情報が足りていないので補正することもできなさそうです。

正確な値が通知される保証はないとは思いますが、表示されるサイズよりも大きな値になっているため、レスポンシブなレイアウトを採用したときに、ギリギリで調整していると要素がはみ出てしまうなどの問題が発生しそうです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0