そのようなウィジェットを作成する方法は?
ウィジェットの作成方法とその機能については、 この記事とこの記事で説明されているため、ウィジェットの作成の詳細については説明しません。
達成する必要がある主なタスクは、標準アプリケーションの標準アイコンおよびウィジェットに可能な限り類似したウィジェットを作成することです。
既製のソリューションを見つける試みは失敗しました。 そのため、 APK Manager ( リバースエンジニアリングに関する記事のおかげ)とAndroid向けGoogleリーダーアプリケーションを選択する必要がありました。ウィジェットが標準に見えることを望みました。 これはそうではないことが判明しました:
もちろん少し似ていますが、必要なものではありません。 私は終えなければなりませんでした:
<?xml version="1.0" encoding="UTF-8"?> <LinearLayout android:orientation="vertical" android:id="@+id/widget" android:background="@drawable/shortcut_selector" android:focusable="true" android:clickable="true" android:layout_width="74.0dip" android:layout_height="82.0dip" xmlns:android="http://schemas.android.com/apk/res/android"> <FrameLayout android:layout_width="fill_parent" android:layout_height="0.0dip" android:layout_weight="1.0" android:paddingTop="3dip"> <FrameLayout android:layout_gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageView android:id="@+id/icon" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/icon" android:scaleType="center" /> <TextView android:textSize="14.0dip" android:textStyle="bold" android:textColor="#ffffffff" android:gravity="center" android:layout_gravity="bottom|right|center" android:id="@+id/widget_counter" android:background="@android:drawable/ic_notification_overlay" android:layout_width="24dip" android:layout_height="24dip" android:singleLine="true" android:shadowColor="#ff000000" android:shadowRadius="1.0"/> </FrameLayout> </FrameLayout> <TextView android:textSize="13.0dip" android:textColor="#ffffffff" android:ellipsize="marquee" android:gravity="center_horizontal" android:layout_gravity="center_horizontal" android:id="@android:id/text1" android:background="@drawable/appwidget_text_background" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="1dip" android:paddingBottom="1dip" android:singleLine="true" android:shadowColor="#ff000000" android:shadowRadius="2.0" android:layout_weight="0.0" android:text="@string/app_name" /> </LinearLayout>
ウィジェットの高さ-82dip- 推奨以上。 ただし、それ以外の場合、ウィジェットは標準アイコンよりも小さくなります。
上記のコードで指定されている@ drawable / shortcut_selectorは、クリック/選択に対するウィジェットの応答方法を記述するxmlファイルです。
<?xml version="1.0" encoding="UTF-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/pressed_application_background" /> <item android:state_focused="true" android:state_window_focused="true" android:drawable="@drawable/focused_application_background" /> <item android:state_focused="true" android:state_window_focused="false" android:drawable="@android:color/transparent" /> </selector>
ここで、最初の問題であるpressed_application_backgroundとfocused_application_background-背景画像に直面しています。 ただし、携帯電話によって背景は異なります。 たとえば、標準のAndroidでは背景がオレンジ、HTCでは緑です。 ソリューションは、標準のAndroidリソースにアクセスする機会となります。AndroidR Drawablesサイトのおかげで、これらのリソースのIDを見つけることさえできます。
- pressed_application_background_static
- focused_application_background_static
ただし、これらのリソースは公開されておらず、アプリケーションで使用することはできません。 android.os.Buildの値を読み取って、OSのタイプを判別しようとすることができます。 しかし、これはウィジェットにとってそれほど重要ではないと判断したので、オレンジ色の背景を残しました(ちなみに、Google Readerウィジェットも同じことをしました)。
2番目の問題は最初の問題に似ています。 標準のAndroidでは未読メッセージの数を含む円の背景は赤、HTCでは緑です。 ただし、ここでは標準リソース@android:drawable / ic_notification_overlayを使用できます。 これは円ではありませんが、非常によく似ています(画像は少し低くなります)。
テキスト背景のハイライトは、変更せずにGoogleリーダーウィジェットから取得しました( appwidget_text_background.xmlファイル):
<?xml version="1.0" encoding="UTF-8"?> <shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#b2191919" /> <padding android:left="5.0dip" android:top="1.0dip" android:right="5.0dip" android:bottom="1.0dip" /> <corners android:radius="8.0dip" /> </shape>
私のアプリケーション (このようなカウンターを備えた他のアプリケーションのように)では、カウンター値を定期的に更新する必要はありません。 したがって、 updatePeriodMillis = "0"であり、その更新は次の2つの場合にのみ発生します。
- データベースで更新が発生したとき。
- アプリケーションが非表示になったとき( onStop() )。
同時に、次のコードを使用してウィジェットを更新します。
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this); int[] a = appWidgetManager.getAppWidgetIds(new ComponentName(this.getPackageName(), "WidgetProvider")); List<AppWidgetProviderInfo> b = appWidgetManager.getInstalledProviders(); for (AppWidgetProviderInfo i : b) { if (i.provider.getPackageName().equals(this.getPackageName())) { a = appWidgetManager.getAppWidgetIds(i.provider); new WidgetProvider().onUpdate(this, appWidgetManager, a); } }
未読メッセージの数がゼロの場合、番号の付いた円は非表示になります。
if (unreadRecordsCount == 0) { views.setViewVisibility(R.id.widget_counter, View.INVISIBLE); views.setTextViewText(R.id.widget_counter, ""); } else { views.setTextViewText(R.id.widget_counter, Long.toString(unreadRecordsCount)); views.setViewVisibility(R.id.widget_counter, View.VISIBLE); }
結果は次のとおりです。
不完全に見えますが、私の意見では非常に似ています。 エミュレータも元のものと非常によく似ています。