2011年5月10日火曜日

複数のサイズを持つウィジェットの作り方

あまり情報が載っていなかったのでメモしておきます。

登録したいウィジェットを AndroidManifest.xml に追加します。
変更するポイントは次の通りです。
  1. receiver の android:name は AppWidgetProvider を継承したクラスを記述する
  2. android:label はウィジェット選択時に表示されるメッセージを設定する
  3. meta-data には res\xml に作成する appwidget-provider リソースを指定する 
[AndroidManifest.xml]
<application
 android:icon="@drawable/icon"
 android:label="@string/app_name">
 <receiver
        android:name=".Widget1x1Provider"
  android:label="@string/widget_1x1_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_1x1" />
    </receiver>
 <receiver
        android:name=".Widget2x2Provider"
  android:label="@string/widget_2x2_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_2x2" />
    </receiver>
 <receiver
        android:name=".Widget4x4Provider"
  android:label="@string/widget_4x4_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data
            android:name="android.appwidget.provider"
            android:resource="@xml/widget_4x4" />
    </receiver>
</application>

android:resource で指定するXMLは以下のような感じです。
ウィジェット別にレイアウトが変わる場合は android:initialLayout を変更します。
なお、今回はサイズに関わらず同じレイアウトを使う前提です。

[widget_2x2.xml]
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:initialLayout="@layout/widget"
    android:minWidth="146dp"
    android:minHeight="146dp"
    android:updatePeriodMillis="0">
</appwidget-provider>

各ウィジェットの別に処理を記述するのもいいのですが、
クラスの宣言に abstract を指定することでコーディングを減らすことが可能です。
意味がわからない方は java 抽象クラス で検索してみてください。

[WidgetProviderBase.java]
package jp.co.capricornus.sample;

// import 部分は省略

public abstract class WidgetProviderBase extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        // 処理内容は省略
    }
}

AndroidManifest.xml の receiver android:name で指定されたクラスを追加します。
レイアウトが同じでウィジェットの処理が変わらない場合は特に記述する必要はありません。

package jp.co.capricornus.sanskrittattoo;
public class Widget1x1Provider extends WidgetProviderBase {
}

AndroidManifest の指定だけで実装できると簡単でいいのですが、
receiver で同一の android:name は無視されてしまうようです。
SDK のコードを確認したほうがいいのかも…

0 件のコメント:

コメントを投稿