ワンクリックで
android-widget-development
Best practices for AppWidget development with RemoteViews, time display, and known limitations
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Best practices for AppWidget development with RemoteViews, time display, and known limitations
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Guidance for creating effective modular skills for Claude. Use when creating or refining skills to ensure they are concise, follow progressive disclosure patterns, and provide appropriate degrees of freedom.
Guidelines for ensuring smooth and race-condition-free theme transitions in Android, specifically regarding icon tinting and state management.
Best practices for effective human-AI pair programming and communication
Clarify touch-target vs visual size when users ask to resize buttons without changing icons.
Choose whether the outer container acts as the touch proxy or remains a layout placeholder to control hit targets.
Best practices for 60fps custom View rendering with zero allocation in onDraw
| name | Android Widget Development |
| description | Best practices for AppWidget development with RemoteViews, time display, and known limitations |
| last_verified | "2026-01-23T00:00:00.000Z" |
| applicable_sdk | Android 8+ (API 26+) |
Last Verified: 2026-01-23 Applicable SDK: Android 8+ (API 26+), tested through Android 15 (API 35) Project Context: OpenFlip uses 5 widget styles (Classic, Glass, Solid, Split, White)
This skill covers AppWidget (home screen widget) development, including time synchronization, RemoteViews limitations, and proven architectural patterns.
Related Skills:
New Features:
Known Limitations (Still Apply):
For widgets showing time, always use TextClock instead of custom solutions:
<TextClock
android:id="@+id/clock_hours"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:format12Hour="h"
android:format24Hour="HH"
android:timeZone="@null" />
| Approach | Result |
|---|---|
| Bitmap screenshot stream | ❌ Background execution limits cause freezing |
| AlarmManager periodic updates | ❌ Inaccurate, delays from seconds to minutes |
| TextClock (system native) | ✅ System-level precision, zero battery drain |
Create an abstract base class to reduce duplication:
abstract class BaseWidget : AppWidgetProvider() {
abstract val layoutId: Int
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
appWidgetIds.forEach { widgetId ->
updateAppWidget(context, appWidgetManager, widgetId)
}
}
protected open fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
widgetId: Int
) {
val views = RemoteViews(context.packageName, layoutId)
setupClickHandlers(context, views)
appWidgetManager.updateAppWidget(widgetId, views)
}
private fun setupClickHandlers(context: Context, views: RemoteViews) {
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP
}
val pendingIntent = PendingIntent.getActivity(
context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
views.setOnClickPendingIntent(R.id.widget_root, pendingIntent)
}
}
[!CAUTION] RemoteViews has strict view hierarchy limits. Complex overlays may cause "Problem loading widget" errors.
Problem: Split-flap style widgets may show white anti-aliasing edges at seams.
Attempted Fix: Overlay a thin View to cover the seam → FAILED
Reason: Adding overlay views may exceed RemoteViews complexity limits.
Decision: Accept the visual artifact. Prioritize widget reliability over pixel-perfect rendering.
To create a split-flap clock effect in widgets:
<!-- Container clips the oversized TextClock -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="59dp"
android:clipChildren="true"
android:clipToPadding="true">
<!-- TextClock is taller than container -->
<TextClock
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_gravity="top|center_horizontal"
android:gravity="center" />
</FrameLayout>
The top half shows upper portion of digits; a separate container shows the bottom half.
In res/xml/widget_info.xml:
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="180dp"
android:minHeight="110dp"
android:targetCellWidth="4"
android:targetCellHeight="2"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen"
android:initialLayout="@layout/widget_layout"
android:previewImage="@drawable/widget_preview"
android:updatePeriodMillis="0" />
Note: updatePeriodMillis="0" when using TextClock (no manual updates needed).
Prevent Activity duplication when launching from widget:
val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP
}