新人成長記録8th(ウィジェット)

ウィジェット作成の紹介をしていきます

ウィジェットとはホーム画面に設置できるモジュールです
今回のウィジェット作成では、ウィジェット作成の方法やイベントの送受信を学びました。
Screenshot_20160822-163450

ウィジェットの機能

作成したウィジェットの基本的な機能は以下の通りです
[カレンダーの表示]
[当日日付の色変更]
[メモ有日付の色変更]
[日付部分のタップでカレンダーアプリへ遷移]
[カレンダーアプリでメモの追加、削除などの変更があるとウィジェットへ反映]
となります

ウィジェットの実装

AndroidStudioでウィジェットを実装する方法は簡単でした
ウィジェットを実装してから、カレンダーを表示するまでに一苦労がありました
それも踏まえて説明していきます

ウィジェットの作成

サイドのProjectウィンドウ内の任意の箇所で右クリックで下記のメニューが出ます
パッケージ名は塗りつぶしています
New>Widget>App Widgetを選択
make1

App Widgetを選択すると下記のウィンドウが出ます
make2
Class Name>名前の設定
好きな名前を入力(java,xml,layoutのファイル名)

Placement>設置可能場所の設定
Home-screen and Keyguard(ホーム画面、ロック画面)
Home-screen only(ホーム画面のみ)
Keyguard only(ロック画面)

Resizable>サイズ変更の設定
Horizontally and vertically(横、縦のサイズを変更可能)
Only horizontally(横のみ変更可能)
Only vertically(縦のみ変更可能)
Not resizable(変更不可)

Minimum Width>最小横幅の設定
1~4

Minimum Height>最小縦幅の設定
1~4

Configration Screen>ウィジェット追加時に設定Activityを表示

それぞれの設定が完了したらFinishをクリックします

すると、ウィジェットのソース(javaフォルダ)、ウィジェットのレイアウト(layoutフォルダ)、ウィジェットの設定(xmlフォルダ)が生成されます
マニフェストにもreceiverタグが追加されているはずです
これでウィジェットを表示するための準備は完了しました
これだけでもapkをインストールすると、ホーム画面にウィジェットを表示することが可能になっています

カレンダーの実装

次はウィジェットの中身を実装していきます
javaファイルとlayoutファイルを編集していきます

ウィジェットでは、動的なレイアウトの生成ができないためにlayoutであるxmlファイルにすべてを書く必要がありました
カレンダーなので日付を表示するTextViewが、最低でも7×6と必要なので、IDの振り分けに少し苦労しました

javaファイルへは、カレンダーの出力処理を追加していきます

ウィジェットではRemoteViewsクラスを使用してレイアウトへの操作を行うので、インスタンスを取得します

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.cal_widget);

 

RemoteViewsクラスのメソッドを利用してレイアウトのパラメータを変更していきます
Text内容を変更する時は、下記のようにします

views.setTextViewText(id, string);

 

setTextViewTextのようにきちんと用意されていないパラメータもあります
そのような時はRemoteViewクラスのset~~メソッドでパラメータの変更をしていきます
下記のプログラムは背景リソースを設定しています

views.setInt(id,"setBackgroundResource",R.drawable.widgetborder);

strId>ViewのID
setBackgroundResource>変更したいパラメータのメソッド(setText, setTextsizeなど、使用できないものもあり)
R.drawable.widgetborder>リソースのdrawableから背景のIDを取得

ちなみに、下記のようにsetTextViewTextをsetCharSequenceで再現できます

views.setCharSequence(id,"setText","setText", string);

 

RemoteViews.set~~メソッドでも変更できない場合があります
それは、Viewクラス内で「@android.view.RemotableViewMethod」と記述されていないメソッドです
例えばTextView.javaのsetTextメソッドは下記のように記述されていました

@android.view.RemotableViewMethod
public final void setText(CharSequence text) {
    setText(text, mBufferType);
}

アプリ起動機能

カレンダーに表示されているViewの中で日付をタップした時のみアプリを起動するように設定します
クリックイベントのセットにはRemoteViewsクラスのsetOnClickPendingIntent(int viewId, PendingIntent pendingIntent)メソッドを使用します
viewId>どのViewにClickイベントをセットするか
pendingIntent>起動したいアプリへのIntentを含むPendingIntentを使用

ウィジェットへのイベント反映

ウィジェットの更新をするには、アプリ側でBroadcastを送信して、ウィジェット側でそれを受信して処理をします

ウィジェット側でイベントを受け取るにはonReceiveを使用します
AppWidgetProviderクラスはBroadcastクラスを継承しているために、新たに継承する必要はありません

アプリ側では更新が必要なタイミングで、ウィジェットへBroadcastを送るように実装しました

Intent widgetIntent = new Intent(this,widget.class);
		sendBroadcast(widgetIntent);

終わりに

ウィジェットに取り掛かり始めの時は、Activityと同様の処理でレイアウトを動的に生成しようとしていて、ホーム画面にウィジェットを出すとなにも表示されませんでした
それに、どうやらエラーにもならないのでなにがいけないのか困惑しました
調査をすると動的に作成はできないということでした(参照サイトは忘れてしまいました)
fragmentとして持ってこようとしたらAppWidgetsでは、fragmentlayoutはフォローされていませんでした
こういった経緯があり、日付をすべてレイアウトファイルに書き込むことになりました

火曜日担当:poppyからでした



アプリ関連ニュース

お問い合わせはこちら

お問い合わせ・ご相談はお電話、またはお問い合わせフォームよりお受け付けいたしております。

tel. 06-6454-8833(平日 10:00~17:00)

お問い合わせフォーム