2011/04/27

ホームウィジェットの中身を入れ子にする方法

おはこんばんにちは、noxiです。読み方は「のぃ」ではなくて「のくしー」です。
ホームウィジェットって使う側からは便利なんですけど、設計する側からすれば凄く面倒くさいですよね。事前にappwidget-providerなるxmlを作成し画面に貼るレイアウトxmlを定義しないといけないですし、使える画面パーツも限られています。

Android1.6(API4)までは、複雑なレイアウトを形成するにあたって、全てのパーツを記述する必要がありました(多分。少なくともWeatherNowのウィジェットは全て書いてる)。

Android2.1(API7)からはそんなことは必要無い! 中に入れるxmlを別々に定義できる! 凄く楽! マジ便利! WeatherNowでも早く使いたい!
そんな方法をちろちろ紹介してみようと思います。

非常に簡単なサンプルコードを紹介します。
・Provider.java(AppWidgetProviderクラス)
・provider.xml(appwidget-provider xml)
・main.xml(appwidget-provider xmlに記載するメインビューxml)
・content.xml(実際に表示するxml)
・content2.xml(実際に表示するxml)
(Manifest.xmlは略)

まずはxmlファイルから順に
・provider.xml

非常に単純な内容の、ホーム1x1占有、自動更新無し、レイアウトxmlはmain.xmlと定義しているだけのappwidget-providerなxmlです。

・main.xml

こちらも非常に単純で、中身は全くありません。ルートとなるFrameLayoutにIDが付いてるだけです。

・content.xml

content.xmlは実際にウィジェットに表示する中身です。テキスト1つ、画像1つ、そして余った領域にLinearLayoutがあります。

・content2.xml

content2.xmlはcontent.xmlのLinearLayout部分に入れてみようかなと思っているレイアウトです。テキスト1つ。

・Provider.java(AppWidgetProviderのonUpdateのところだけ)

非常に簡単なコードですが、ビューを入れ子にしています。Android2.1からRemoteViews#addViewが使えるようになったので、Viewを使い回すことが可能になり、大変便利になりました。includeタグが使えないホームウィジェットにおいて、Viewの使い回しが出来るって凄く素敵だと思います(天気ウィジェットを作っている身としては。今日の天気も明日の天気も同じレイアウトなので)。
xmlメンテナンスの面から、1.6対応を切りたくなりますよね。


WeatherNowは以前にも書きました通り、Android2.3の次のスマートフォン向けOS発表、またはAndroid1.6ユーザーが全体の0.5%を切った時点で1.6サポートを打ち切りますので予めご了承下さい。