Reputation: 4187
I have a home screen widget for my app. It does the job fine, updating a counter (the default Flutter example), but sometimes, it takes a few seconds to refresh.
I'm trying to display a spinner, blocking the Update Counter button, and remove it when I get the callback, but it doesn't work.
For this, I'm trying this package: https://pub.dev/packages/home_widget
This is what I have so far:
main.dart:
import 'package:flutter/material.dart';
import 'package:home_widget/home_widget.dart';
import 'package:porftolio_investments/theme/theme.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
HomeWidget.registerInteractivityCallback(backgroundCallback);
runApp(const MyApp());
}
Future<void> backgroundCallback(Uri? uri) async {
if (uri?.host == 'updatecounter') {
int counter = 0;
await HomeWidget.getWidgetData('_counter', defaultValue: 0).then((value) {
counter = value!;
counter++;
});
await HomeWidget.saveWidgetData('_counter', counter);
await HomeWidget.updateWidget(
name: 'HomeScreenWidgetProvider',
iOSName: 'HomeScreenWidgetProvider',
);
}
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'Porfolio Investments',
theme: darkMode,
// home: const LandingPage(),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
@override
void initState() {
super.initState();
HomeWidget.widgetClicked.listen((Uri? uri) => loadData());
loadData();
}
void _incrementCounter() {
setState(() {
_counter++;
});
updateAppWidget();
}
void loadData() async {
await HomeWidget.getWidgetData('_counter', defaultValue: 0).then((value) {
setState(() {
_counter = value!;
});
});
}
Future<void> updateAppWidget() async {
await HomeWidget.saveWidgetData('_counter', _counter);
await HomeWidget.updateWidget(
name: 'HomeScreenWidgetProvider',
iOSName: 'HomeScreenWidgetProvider',
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
widget_layout.xml:
<FrameLayout
android:id="@+id/widget_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="180dp"
android:layout_height="110dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#1f303d">
<TextView
android:id="@+id/tv_counter"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:gravity="center_horizontal"
android:padding="12dp"
android:text="--"
android:textColor="@android:color/white"
android:textSize="16sp" />
<Button
android:id="@+id/bt_update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Update Counter"
android:textColor="@android:color/holo_blue_dark"
android:textSize="12sp" />
</RelativeLayout>
</FrameLayout>
widget_info.xml:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_layout"
android:minWidth="150dp"
android:minHeight="200dp"
android:minResizeWidth="200dp"
android:minResizeHeight="150dp"
android:widgetCategory="home_screen" />
WidgetProvider.kt:
class HomeScreenWidgetProvider : HomeWidgetProvider() {
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray, widgetData: SharedPreferences) {
appWidgetIds.forEach { widgetId ->
val views = RemoteViews(context.packageName, R.layout.widget_layout).apply {
// Open App on Widget Click
val pendingIntent = HomeWidgetLaunchIntent.getActivity(context,
MainActivity::class.java)
setOnClickPendingIntent(R.id.widget_root, pendingIntent)
val counter = widgetData.getInt("_counter", 0)
var counterText = "Your counter value is: $counter"
if (counter == 0) {
counterText = "You have not pressed the counter button"
}
setTextViewText(R.id.tv_counter, counterText)
// Pending intent to update counter on button click
val backgroundIntent = HomeWidgetBackgroundIntent.getBroadcast(context,
Uri.parse("myAppWidget://updatecounter"))
setOnClickPendingIntent(R.id.bt_update, backgroundIntent)
}
appWidgetManager.updateAppWidget(widgetId, views)
}
}
}
AndroidManifest.xml:
<receiver
android:name="HomeScreenWidgetProvider"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
<!-- home screen widget -->
<!-- HomeWidget background receiver -->
<receiver
android:name="es.antonborri.home_widget.HomeWidgetBackgroundReceiver"
android:exported="true">
<intent-filter>
<action android:name="es.antonborri.home_widget.action.BACKGROUND" />
</intent-filter>
</receiver>
<!-- HomeWidget background service -->
<service
android:name="es.antonborri.home_widget.HomeWidgetBackgroundService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true" />
Upvotes: 0
Views: 34