ウィジェットを作りたい気持ちDrivenな記事、第3回です。
Androidのウィジェットの開発に関する記事です。公式ドキュメントApp Widgetsの訳を中心に記事を書いていきます。
間違いを見つけた場合、コメントで指摘していただけると幸いです。
リソースフォルダ編の後編です。
第3回では、ウィジェットのレイアウトファイルについて翻訳していきます。
ウィジェットのレイアウトを作る
ウィジェットはレイアウトを定義するための、xmlファイルのレイアウトリソースが必要になります。レイアウトファイルは (ActivityやFragment同様) res/layout
に保存されている必要があります。
一部のViewオブジェクトは、ウィジェットのレイアウトリソースに使うことができないので注意が必要です。ウィジェットのレイアウトを作る場合は、App Widget Design Guidelines に従うことが推奨されています。
レイアウトの記事の内容について慣れているならば、ウィジェットのレイアウトを作ることは難しくありません。しかし、ウィジェットのレイアウトは、RemoteViews の上に作られる点に気をつけなければなりません。RemoteViews
では、全ての layout
と view
がサポートされている訳ではありません。
RemoteViews でサポートされている layout
オブジェクト
RemoteViews
クラスでサポートされている (すなわちウィジェットで利用可能な) レイアウトクラスは以下の4種類です。
RemoteViews でサポートされている view
オブジェクト
RemoteViews
クラスでサポートされている widget class
は以下の12種類です。
View クラスとは書かれていませんでしたが、以下全て、
android.view.View
継承クラスなので、ウィジェットで利用可能な View という理解で良さそうです。
- AnalogClock
- Button
- Chronometer
- ImageButton
- ImageView
- ProgressBar
- TextView
- ViewFlipper
- ListView
- GridView
- StackView
- AdapterViewFlipper
Custom View について
RemoteViews
では、CustomView のサポートはしていないので、独自 View はウィジェットでは使えません。
ViewStub について
RemoteViews
では、ViewStub のサポートをしています。ウィジェットがレイアウトリソースを inflate
するタイミングでは、読み込ませたくない View があるならば、ViewStub を使用することができます。
ViewStub
は、invisible
かつzero-sized
な View であり、setVisibility(int)
かinflate()
メソッドが、配置されている ViewStub に対して要求された時に、配置された ViewStub と入れ替わりにandroid:layout
に指定されているレイアウトリソースが読み込まれる。
マージンについて
通常、ウィジェットは画面端からは離れていることが推奨されます。また、他のウィジェットと同一平面上に存在することも避けるべきです。
should not visually be flush with other widgets の訳なのですが、他のウィジェットとの間にマージンがないといけない、という感じでしょうか。
以上の理由により、ウィジェットのレイアウトの周囲にマージンを入れる必要があります。
Android4.0 からは、ウィジェットと、ウィジェットが入っているグリッドの間に自動的に padding
が設定されます。これにより、他のウィジェットやアプリのアイコンと並べた時にも、より良いレイアウトを提供することができます。この機能は強く推奨されており、ウィジェットの targetSdkVersion
を 14 以上に設定することが求められています。
Android4.0 以前のプラットフォームに対応する場合
Android4.0 以降のプラットフォームで、余計なマージンを表示することなく、Android4.0 以前のプラットフォームでマージンをウィジェットの周囲に設定することができます。(もうその必要はほとんどなさそうですが。)
作業手順は以下の通りです。
1. targetSdkVersion
を 14 以上に設定します。
2. ウィジェットのレイアウトファイルに、android:padding
を設定して、dimension
リソース (res/values/dimens/...
)の値を参照させます。
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="@dimen/widget_margin">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:background="@drawable/my_widget_background">
…
</LinearLayout>
</FrameLayout>
3. res/values
に Android4.0 未満、Android4.0 以降の2種類の dimens.xml
を作成して、それぞれに padding
を定義します。
res/values/dimens.xml:
<dimen name="widget_margin">8dp</dimen>
res/values-v14/dimens.xml:
<dimen name="widget_margin">0dp</dimen>
それ以外
nine-patch を変更する方法もあるみたいです。デフォルトで設定されているnine-patch background asset
に対して、マージンを設定します。同時に、APIレベル 14 以上の端末用のマージンが入っていない nine-patch
を用意すれば、res/values
を使うのと同じような結果が得られます。
さいごに
以上で、ウィジェットに使用するリソースの部分は終わりです。
次は、ソース (AppWidgetProvider継承クラス) の部分について触れていきます。