From c5b1293a9000f73acdf76b93e161dc15cbf6182b Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Sun, 15 Aug 2021 11:43:22 -0600 Subject: [PATCH] widgets: add compact/mini forms Add two new widget forms. The compact widget form shows the cover art [this time with a proper aspect ratio] but no controls. The mini form only shows the metadata. This seems to work well enough and provides more choices with how one wants to decorate their homescreen with Auxio's widgets. --- app/build.gradle | 2 + .../java/org/oxycblt/auxio/widgets/Forms.kt | 33 ++++++++-- .../oxycblt/auxio/widgets/WidgetProvider.kt | 21 ++++--- .../res/drawable/ui_widget_aspect_ratio.xml | 11 ++++ app/src/main/res/layout/widget_compact.xml | 63 +++++++++++++++++++ app/src/main/res/layout/widget_mini.xml | 26 ++++++++ app/src/main/res/xml-v31/widget_info.xml | 6 +- app/src/main/res/xml/widget_info.xml | 2 +- 8 files changed, 147 insertions(+), 17 deletions(-) create mode 100644 app/src/main/res/drawable/ui_widget_aspect_ratio.xml create mode 100644 app/src/main/res/layout/widget_compact.xml create mode 100644 app/src/main/res/layout/widget_mini.xml diff --git a/app/build.gradle b/app/build.gradle index a3e59cc66..1835989ee 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -99,6 +99,8 @@ dependencies { // Material implementation "com.google.android.material:material:1.4.0" + implementation 'me.zhanghai.android.fastscroll:library:1.1.7' + // --- DEBUG --- // Lint diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt index 8bf4036fc..7eaab084e 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/Forms.kt @@ -41,7 +41,12 @@ private fun createViews( return views } -private fun RemoteViews.applyState(context: Context, state: WidgetState) { +private fun RemoteViews.applyMeta(context: Context, state: WidgetState) { + setTextViewText(R.id.widget_song, state.song.name) + setTextViewText(R.id.widget_artist, state.song.album.artist.name) +} + +fun RemoteViews.applyControls(context: Context, state: WidgetState) { setOnClickPendingIntent( R.id.widget_skip_prev, context.newBroadcastIntent( @@ -63,9 +68,6 @@ private fun RemoteViews.applyState(context: Context, state: WidgetState) { ) ) - setTextViewText(R.id.widget_song, state.song.name) - setTextViewText(R.id.widget_artist, state.song.album.artist.name) - setImageViewResource( R.id.widget_play_pause, if (state.isPlaying) { @@ -74,7 +76,9 @@ private fun RemoteViews.applyState(context: Context, state: WidgetState) { R.drawable.ic_play } ) +} +fun RemoteViews.applyCover(context: Context, state: WidgetState) { if (state.albumArt != null) { setImageViewBitmap(R.id.widget_cover, state.albumArt) setContentDescription( @@ -90,15 +94,32 @@ fun createDefaultWidget(context: Context): RemoteViews { return createViews(context, R.layout.widget_default) } +fun createMiniWidget(context: Context, state: WidgetState): RemoteViews { + val views = createViews(context, R.layout.widget_mini) + views.applyMeta(context, state) + return views +} + +fun createCompactWidget(context: Context, state: WidgetState): RemoteViews { + val views = createViews(context, R.layout.widget_compact) + views.applyMeta(context, state) + views.applyCover(context, state) + return views +} + fun createSmallWidget(context: Context, state: WidgetState): RemoteViews { val views = createViews(context, R.layout.widget_small) - views.applyState(context, state) + views.applyMeta(context, state) + views.applyCover(context, state) + views.applyControls(context, state) return views } fun createFullWidget(context: Context, state: WidgetState): RemoteViews { val views = createViews(context, R.layout.widget_full) - views.applyState(context, state) + views.applyMeta(context, state) + views.applyCover(context, state) + views.applyControls(context, state) views.setOnClickPendingIntent( R.id.widget_loop, diff --git a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt index da3933872..1a167c66f 100644 --- a/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt +++ b/app/src/main/java/org/oxycblt/auxio/widgets/WidgetProvider.kt @@ -38,10 +38,13 @@ import org.oxycblt.auxio.ui.isLandscape * Auxio's one and only appwidget. This widget follows a more unorthodox approach, effectively * packing what could be considered 3 or 4 widgets into a single responsive widget. More specifically: * + * - For widgets 2x1 or lower, show a text-only view with no controls + * - For widgets Wx1 or lower, show a compact view with no controls. * - For widgets Wx2 or higher, show an expanded view with album art and basic controls * - For widgets 4x2 or higher, show a complete view with all playback controls * - * Other widget variants might be added if there is sufficient demand. + * There are some minor problems with this implementation [notably UI jittering when the widget + * picks a new layout below Android 12], but this is tolerable. * * For more specific details about these sub-widgets, see Forms.kt. */ @@ -68,9 +71,13 @@ class WidgetProvider : AppWidgetProvider() { ) // Map each widget form to the cells where it would look at least okay. + // The large widgets are 140 instead of 110 so that they're backwards compatible + // with the old widget size reporting val views = mapOf( - SizeF(180f, 110f) to createSmallWidget(context, state), - SizeF(250f, 110f) to createFullWidget(context, state) + SizeF(180f, 40f) to createMiniWidget(context, state), + SizeF(250f, 40f) to createCompactWidget(context, state), + SizeF(180f, 140f) to createSmallWidget(context, state), + SizeF(250f, 140f) to createFullWidget(context, state) ) appWidgetManager.applyViewsCompat(context, views) @@ -138,8 +145,8 @@ class WidgetProvider : AppWidgetProvider() { updateAppWidget(name, RemoteViews(views)) } else { // Otherwise, we try our best to backport the responsive behavior to older versions. - // This is mostly a guess based on RemoteView's documentation. It may be improved when - // Android 12's source is released. + // This is mostly a guess based on RemoteView's documentation. It seems to work well + // on most launchers. It may be improved when Android 12's source is released. // Each widget has independent dimensions, so we iterate through them all // and do this for each. @@ -168,8 +175,8 @@ class WidgetProvider : AppWidgetProvider() { height = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT) } - height += padW - width += padH + height += padH + width += padW logD("Assuming true widget dimens are ${width}x$height") diff --git a/app/src/main/res/drawable/ui_widget_aspect_ratio.xml b/app/src/main/res/drawable/ui_widget_aspect_ratio.xml new file mode 100644 index 000000000..4eb6d9199 --- /dev/null +++ b/app/src/main/res/drawable/ui_widget_aspect_ratio.xml @@ -0,0 +1,11 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/widget_compact.xml b/app/src/main/res/layout/widget_compact.xml new file mode 100644 index 000000000..92907f1f1 --- /dev/null +++ b/app/src/main/res/layout/widget_compact.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/widget_mini.xml b/app/src/main/res/layout/widget_mini.xml new file mode 100644 index 000000000..108f15978 --- /dev/null +++ b/app/src/main/res/layout/widget_mini.xml @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/app/src/main/res/xml-v31/widget_info.xml b/app/src/main/res/xml-v31/widget_info.xml index 76612407c..963846a3d 100644 --- a/app/src/main/res/xml-v31/widget_info.xml +++ b/app/src/main/res/xml-v31/widget_info.xml @@ -3,10 +3,10 @@ android:description="@string/info_widget_desc" android:initialLayout="@layout/widget_small" android:minResizeWidth="180dp" - android:minResizeHeight="110dp" + android:minResizeHeight="40dp" android:previewLayout="@layout/widget_small" android:resizeMode="horizontal|vertical" - android:targetCellWidth="3" - android:targetCellHeight="2" + android:minWidth="180dp" + android:minHeight="110dp" android:updatePeriodMillis="0" android:widgetCategory="home_screen" /> \ No newline at end of file diff --git a/app/src/main/res/xml/widget_info.xml b/app/src/main/res/xml/widget_info.xml index f74fde98b..828a11bae 100644 --- a/app/src/main/res/xml/widget_info.xml +++ b/app/src/main/res/xml/widget_info.xml @@ -4,7 +4,7 @@ android:minWidth="180dp" android:minHeight="110dp" android:minResizeWidth="180dp" - android:minResizeHeight="110dp" + android:minResizeHeight="40dp" android:previewImage="@drawable/ui_widget_preview" android:resizeMode="horizontal|vertical" android:updatePeriodMillis="0"