0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Jetpack Glance始め方

Posted at

概要

Jetpack Glanceを使ってウィジェットを作ってみたので覚え書きです。
大体は公式の手順を参照して作ることができますが、躓いたところなどをメモ。

公式の手順は以下の2つ

手順

①セットアップ

依存関係など追加します。

build.gradle
dependencies {
   implementation "androidx.glance:glance-appwidget:1.1.1"
   // Material3ならそれ用のものを使うこと
   implementation "androidx.glance:glance-material:1.1.1"
}

②メタデータファイルの作成

ウィジェット用のXMLファイルを作成して、メタデータを定義します。

my_app_widget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/glance_default_loading_layout"
    android:minWidth="110dp"
    android:minHeight="40dp"
    android:previewImage="@null"
    android:resizeMode="none"
    android:updatePeriodMillis="0"
    android:widgetCategory="home_screen" />

各属性が何を意味しているかは、以下のページを参考にします。

initialLayoutはライブラリ側で用意されているものになります。
ウィジェットの初期表示になるので、エラーでうまく読み込めない時はローディング表示から切り替わらなかったりします。

③ウィジェットのUI定義とインスタンスの作成

実際のウィジェットのUIはJetpakck Composeにかなり近い感覚で書けます。
ただし同じように使えないものもあるので注意が必要です。
特にstringResourceやcolorResourceが使えないのでcontextから引っ張ってくる必要があるのですが、もし使ってもコンパイルエラーにはなりません。
しかしいざ表示すると「コンテンツを表示できません」と表示されます。

GlanceSnipetts.kt
private object GlanceCreateAppWidgetSnippet {
    class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
        override val glanceAppWidget: GlanceAppWidget = MyAppWidget()
    }

    class MyAppWidget : GlanceAppWidget() {
        override suspend fun provideGlance(context: Context, id: GlanceId) {
            provideContent {
                WidgetContent()
            }
        }

        // ほぼほぼJetpack Composeと同じ要領で書ける
        // コンポーザブルはglance専用のものを使うことに注意
        // 以前のAppWidgetとRemoteViewsの制限に制約されているから
        @SuppressLint("RestrictedApi")
        @Composable
        private fun WidgetContent() {
            Column(
                // ModifierはGlanceModifierを使う
                modifier = GlanceModifier
                    .fillMaxSize()
                    // colorResourceも使えないのでColorProviderを使う
                    .background(ColorProvider(R.color.white)),
                verticalAlignment = Alignment.CenterVertically,
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Text(
                    text = glanceString(R.string.hoge),
                    modifier = GlanceModifier.padding(12.dp)
                )

                Button(
                    text = "GO!!",
                    onClick = { // TODO }
                )
            }
        }

        // stringResourceは使えないため以下のような関数を用意した方がよさそう
        @Composable
        private fun glanceString(@StringRes id: Int): String {
            return LocalContext.current.getString(id)
        }
    }
}

④レシーバー設定

ウィジェットの追加や更新はBroadcastReceiver経由で行われるので、こちらを設定しておきます。
これを設定しておかないと、②で言及した無限ロード状態になってしまいます。

GlanceSnipetts.kt
private object GlanceCreateAppWidgetSnippet {
    ...
}

class MyAppWidgetReceiver : GlanceAppWidgetReceiver() {
    override val glanceAppWidget: GlanceAppWidget = GlanceCreateAppWidgetSnippet.MyAppWidget()
}

⑤マニフェストでウィジェットを宣言する

AndroidManifest.xmlでウィジェットの使用宣言をします。
name属性には④で設定したレシーバーを、メタデータには②で設定したファイルを定義します。

AndroidManifest.xml
<!-- ⑤マニフェスト宣言 -->
    <application>
        <receiver
            android:name=".hoge.glance.MyAppWidgetReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/my_app_widget_info" />
    </application>

以上になります。
あとはアプリの要件に合わせて良い感じにカスタマイズしていきましょう。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?