簡単にウィジェットを表示したり、アプリから更新する方法を知りたい人向け。
ウィジェットを表示するためには、レイアウトファイルとかを作成したり、マニフェストファイルを修正する必要があるが、Android Studioだと基本的なことはすべてやってくれるので、ほぼ何もしなくてもいい。具体的にはプロジェクトのツリービューの右クリック→NewからWidgetを選択するとウィザードが開くので入力していくだけ。
まずはレイアウトファイルで表示する部品などを登録しておく。使用できるレイアウトや部品については制限があるので注意。
基本的な仕組みはこんな感じ。ウィジェットを新規に表示させたり、更新時間になるとonUpdateが実行される。その後、updateAppWidgetが呼ばれる。こうなっているのは、複数のウィジェットを表示させることができるからで、複数のウィジェットに同時に何か変更を加える場合にはonUpdateで、個別のウィジェットで表示を変えたい場合にはupdateAppWidgetのほうでいろいろやる。
アプリからウィジェットをいじる場合には、下記のようなコードを実行することで変更することができる
こんな感じで実装すればデータの更新はすべてproviderクラスのほうで行われるので見通しがよくなる。
ウィジェットを表示するためには、レイアウトファイルとかを作成したり、マニフェストファイルを修正する必要があるが、Android Studioだと基本的なことはすべてやってくれるので、ほぼ何もしなくてもいい。具体的にはプロジェクトのツリービューの右クリック→NewからWidgetを選択するとウィザードが開くので入力していくだけ。
まずはレイアウトファイルで表示する部品などを登録しておく。使用できるレイアウトや部品については制限があるので注意。
基本的な仕組みはこんな感じ。ウィジェットを新規に表示させたり、更新時間になるとonUpdateが実行される。その後、updateAppWidgetが呼ばれる。こうなっているのは、複数のウィジェットを表示させることができるからで、複数のウィジェットに同時に何か変更を加える場合にはonUpdateで、個別のウィジェットで表示を変えたい場合にはupdateAppWidgetのほうでいろいろやる。
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
// There may be multiple widgets active, so update all of them
for (appWidgetId in appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId)
}
}
companion object {
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) {
//ビューを取得して文字を設定する
val views = RemoteViews(context.packageName, R.layout.test_widget)
views.setTextViewText(R.id.tvHeight, "height")
views.setTextViewText(R.id.tvWeight, "weight")
//ウィジェットIDとviewを渡して設定する
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
アプリからウィジェットをいじる場合には、下記のようなコードを実行することで変更することができる
//AppWidgetManagerから、このウィジェットが登録されているウィジェットIDをすべて取得する
//それぞれについてウィジェットの中身を更新する
val manager: AppWidgetManager = AppWidgetManager.getInstance(this)
for (appWidgetID: Int in manager.getAppWidgetIds(ComponentName(this, BMILogWidget::class.java)))
{
val views = RemoteViews(this.packageName, R.layout.bmilog_widget)
views.setTextViewText(R.id.tvHeight, "ぬぬぬ")
manager.updateAppWidget(appWidgetID, views)
}
他のクラス以外からも上記でウィジェットの中身を触れるが、自動的に作成されるAppWidgetProviderの継承クラス(onUpdate、updateAppWidgetのメソッドのあるクラス)に実装したほうがいいと思う。こんな感じで実装すればデータの更新はすべてproviderクラスのほうで行われるので見通しがよくなる。
companion object {
internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManager,
appWidgetId: Int) {
}
internal fun setText(context: Context, text: String) {
val manager: AppWidgetManager = AppWidgetManager.getInstance(context)
for (appWidgetID: Int in manager.getAppWidgetIds(ComponentName(context, BMILogWidget::class.java))) {
val views = RemoteViews(context.packageName, R.layout.test_widget)
views.setTextViewText(R.id.tvHeight, text)
manager.updateAppWidget(appWidgetID, views)
}
}
}