From 5e2a3d3a90ca5061163bcc200174d2a472479638 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 16 Aug 2025 04:36:42 +0530 Subject: [PATCH 1/3] Backport dynamic layout for search widget --- app/build.gradle | 1 + .../wikipedia/widgets/WidgetProviderSearch.kt | 58 +++++++++++-------- gradle/libs.versions.toml | 2 + 3 files changed, 36 insertions(+), 25 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e7817a8359f..74cef3b8b11 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -185,6 +185,7 @@ dependencies { implementation libs.material implementation libs.appcompat implementation libs.core.ktx + implementation libs.androidx.core.remoteviews implementation libs.browser implementation libs.constraintlayout implementation libs.fragment.ktx diff --git a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt index f6f3633a4ef..acbd3ac18ce 100644 --- a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt +++ b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt @@ -7,9 +7,11 @@ import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Build -import android.util.SizeF +import android.os.Bundle import android.widget.RemoteViews import androidx.core.app.PendingIntentCompat +import androidx.core.util.SizeFCompat +import androidx.core.widget.updateAppWidget import org.wikipedia.Constants.InvokeSource import org.wikipedia.R import org.wikipedia.search.SearchActivity @@ -17,34 +19,40 @@ import org.wikipedia.search.SearchActivity class WidgetProviderSearch : AppWidgetProvider() { override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { val thisWidget = ComponentName(context, WidgetProviderSearch::class.java) - val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) - for (widgetId in allWidgetIds) { - - val pendingIntent = PendingIntentCompat.getActivity(context, 0, - SearchActivity.newIntent(context, InvokeSource.WIDGET, null) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), - PendingIntent.FLAG_UPDATE_CURRENT, false) + for (widgetId in appWidgetManager.getAppWidgetIds(thisWidget)) { + updateWidget(context, appWidgetManager, widgetId) + } + } - val largeView = RemoteViews(context.packageName, R.layout.widget_search_large) - largeView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) + override fun onAppWidgetOptionsChanged( + context: Context, + appWidgetManager: AppWidgetManager, + appWidgetId: Int, + newOptions: Bundle, + ) { + // appWidgetManager.updateAppWidget must be called here on API levels < 31 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { + updateWidget(context, appWidgetManager, appWidgetId) + } + } - val remoteViews = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - val smallView = RemoteViews(context.packageName, R.layout.widget_search_small) - val mediumView = RemoteViews(context.packageName, R.layout.widget_search_medium) - smallView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) - mediumView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) + private fun updateWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) { + val small = SizeFCompat(32f, 32f) + val medium = SizeFCompat(64f, 32f) + val large = SizeFCompat(160f, 32f) + val pendingIntent = PendingIntentCompat.getActivity(context, 0, + SearchActivity.newIntent(context, InvokeSource.WIDGET, null) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + PendingIntent.FLAG_UPDATE_CURRENT, false) - val viewMapping: Map = mapOf( - SizeF(32f, 32f) to smallView, - SizeF(64f, 32f) to mediumView, - SizeF(160f, 32f) to largeView - ) - RemoteViews(viewMapping) - } else { - largeView + appWidgetManager.updateAppWidget(appWidgetId, listOf(small, medium, large)) { + val remoteViewId = when (it) { + small -> R.layout.widget_search_small + medium -> R.layout.widget_search_medium + else -> R.layout.widget_search_large } - - appWidgetManager.updateAppWidget(widgetId, remoteViews) + RemoteViews(context.packageName, remoteViewId) + .apply { setOnClickPendingIntent(R.id.widget_container, pendingIntent) } } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index af3990c09fe..9d53bbd6c21 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,7 @@ coilCompose = "3.3.0" commonsLang3 = "3.18.0" constraintlayout = "2.2.1" coreKtx = "1.17.0" +coreRemoteviews = "1.1.0" desugar_jdk_libs = "2.1.5" drawerlayout = "1.2.0" espressoVersion = "3.7.0" @@ -55,6 +56,7 @@ composeViewModel = "2.9.3" [libraries] android-sdk = { module = "org.maplibre.gl:android-sdk", version.ref = "androidSdk" } android-plugin-annotation-v9 = { module = "org.maplibre.gl:android-plugin-annotation-v9", version.ref = "androidPluginAnnotationV9" } +androidx-core-remoteviews = { module = "androidx.core:core-remoteviews", version.ref = "coreRemoteviews" } androidx-espresso-intents = { module = "androidx.test.espresso:espresso-intents", version.ref = "espressoVersion" } androidx-junit = { module = "androidx.test.ext:junit", version.ref = "junitVersion" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" } From 0d6dabb881dc463fe9e5de50b4c7ab2638e01f86 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Sat, 16 Aug 2025 07:08:26 +0530 Subject: [PATCH 2/3] Reduce some lines of code --- .../java/org/wikipedia/widgets/WidgetProviderSearch.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt index acbd3ac18ce..56b90503246 100644 --- a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt +++ b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt @@ -24,12 +24,8 @@ class WidgetProviderSearch : AppWidgetProvider() { } } - override fun onAppWidgetOptionsChanged( - context: Context, - appWidgetManager: AppWidgetManager, - appWidgetId: Int, - newOptions: Bundle, - ) { + override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, + appWidgetId: Int, newOptions: Bundle) { // appWidgetManager.updateAppWidget must be called here on API levels < 31 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { updateWidget(context, appWidgetManager, appWidgetId) From 67022ebd5ab19ac5547cb13e89876f11149552a3 Mon Sep 17 00:00:00 2001 From: Isira Seneviratne Date: Mon, 15 Sep 2025 06:17:04 +0530 Subject: [PATCH 3/3] Apply code review suggestion --- app/build.gradle | 1 - .../wikipedia/widgets/WidgetProviderSearch.kt | 54 +++++++++---------- app/src/main/res/xml-v31/widget_search.xml | 13 +++++ app/src/main/res/xml/widget_search.xml | 9 +--- gradle/libs.versions.toml | 2 - 5 files changed, 40 insertions(+), 39 deletions(-) create mode 100644 app/src/main/res/xml-v31/widget_search.xml diff --git a/app/build.gradle b/app/build.gradle index 74cef3b8b11..e7817a8359f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -185,7 +185,6 @@ dependencies { implementation libs.material implementation libs.appcompat implementation libs.core.ktx - implementation libs.androidx.core.remoteviews implementation libs.browser implementation libs.constraintlayout implementation libs.fragment.ktx diff --git a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt index 56b90503246..f6f3633a4ef 100644 --- a/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt +++ b/app/src/main/java/org/wikipedia/widgets/WidgetProviderSearch.kt @@ -7,11 +7,9 @@ import android.content.ComponentName import android.content.Context import android.content.Intent import android.os.Build -import android.os.Bundle +import android.util.SizeF import android.widget.RemoteViews import androidx.core.app.PendingIntentCompat -import androidx.core.util.SizeFCompat -import androidx.core.widget.updateAppWidget import org.wikipedia.Constants.InvokeSource import org.wikipedia.R import org.wikipedia.search.SearchActivity @@ -19,36 +17,34 @@ import org.wikipedia.search.SearchActivity class WidgetProviderSearch : AppWidgetProvider() { override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) { val thisWidget = ComponentName(context, WidgetProviderSearch::class.java) - for (widgetId in appWidgetManager.getAppWidgetIds(thisWidget)) { - updateWidget(context, appWidgetManager, widgetId) - } - } + val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget) + for (widgetId in allWidgetIds) { - override fun onAppWidgetOptionsChanged(context: Context, appWidgetManager: AppWidgetManager, - appWidgetId: Int, newOptions: Bundle) { - // appWidgetManager.updateAppWidget must be called here on API levels < 31 - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { - updateWidget(context, appWidgetManager, appWidgetId) - } - } + val pendingIntent = PendingIntentCompat.getActivity(context, 0, + SearchActivity.newIntent(context, InvokeSource.WIDGET, null) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), + PendingIntent.FLAG_UPDATE_CURRENT, false) + + val largeView = RemoteViews(context.packageName, R.layout.widget_search_large) + largeView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) - private fun updateWidget(context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int) { - val small = SizeFCompat(32f, 32f) - val medium = SizeFCompat(64f, 32f) - val large = SizeFCompat(160f, 32f) - val pendingIntent = PendingIntentCompat.getActivity(context, 0, - SearchActivity.newIntent(context, InvokeSource.WIDGET, null) - .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), - PendingIntent.FLAG_UPDATE_CURRENT, false) + val remoteViews = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val smallView = RemoteViews(context.packageName, R.layout.widget_search_small) + val mediumView = RemoteViews(context.packageName, R.layout.widget_search_medium) + smallView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) + mediumView.setOnClickPendingIntent(R.id.widget_container, pendingIntent) - appWidgetManager.updateAppWidget(appWidgetId, listOf(small, medium, large)) { - val remoteViewId = when (it) { - small -> R.layout.widget_search_small - medium -> R.layout.widget_search_medium - else -> R.layout.widget_search_large + val viewMapping: Map = mapOf( + SizeF(32f, 32f) to smallView, + SizeF(64f, 32f) to mediumView, + SizeF(160f, 32f) to largeView + ) + RemoteViews(viewMapping) + } else { + largeView } - RemoteViews(context.packageName, remoteViewId) - .apply { setOnClickPendingIntent(R.id.widget_container, pendingIntent) } + + appWidgetManager.updateAppWidget(widgetId, remoteViews) } } } diff --git a/app/src/main/res/xml-v31/widget_search.xml b/app/src/main/res/xml-v31/widget_search.xml new file mode 100644 index 00000000000..d4d6052709e --- /dev/null +++ b/app/src/main/res/xml-v31/widget_search.xml @@ -0,0 +1,13 @@ + + diff --git a/app/src/main/res/xml/widget_search.xml b/app/src/main/res/xml/widget_search.xml index f28f7369ef0..a78c90d2ace 100644 --- a/app/src/main/res/xml/widget_search.xml +++ b/app/src/main/res/xml/widget_search.xml @@ -1,16 +1,11 @@ - \ No newline at end of file + android:description="@string/widget_description_search"/> diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9d53bbd6c21..af3990c09fe 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,6 @@ coilCompose = "3.3.0" commonsLang3 = "3.18.0" constraintlayout = "2.2.1" coreKtx = "1.17.0" -coreRemoteviews = "1.1.0" desugar_jdk_libs = "2.1.5" drawerlayout = "1.2.0" espressoVersion = "3.7.0" @@ -56,7 +55,6 @@ composeViewModel = "2.9.3" [libraries] android-sdk = { module = "org.maplibre.gl:android-sdk", version.ref = "androidSdk" } android-plugin-annotation-v9 = { module = "org.maplibre.gl:android-plugin-annotation-v9", version.ref = "androidPluginAnnotationV9" } -androidx-core-remoteviews = { module = "androidx.core:core-remoteviews", version.ref = "coreRemoteviews" } androidx-espresso-intents = { module = "androidx.test.espresso:espresso-intents", version.ref = "espressoVersion" } androidx-junit = { module = "androidx.test.ext:junit", version.ref = "junitVersion" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationCompose" }