flutter 每次收到通知后更新状态

htrmnn0y  于 2023-02-05  发布在  Flutter
关注(0)|答案(1)|浏览(154)

我有一个应用程序,它使用包含一些数据的本地通知。在本例中,它是从JSON文件中读取的一些引用。
我想做的是每分钟阅读另一个报价,并在主屏幕上更新它。

void main() {
  runApp(ChangeNotifierProvider<QuotesRepository>(
    create: (context) => QuotesRepository.instance(),
    child: MaterialApp(
      debugShowCheckedModeBanner: false,
      home: MyApp(),
    ),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    var quote = Provider.of<QuotesRepository>(context);
    quote.showScheduledNotification();

    return Scaffold(
      appBar: new AppBar(
        backgroundColor: Colors.red,
        title: new Text('Flutter notification demo'),
      ),
      body: new Center(
        child: Text(
          quote.lastMessage.toString(),
          style: GoogleFonts.clickerScript(fontSize: 40.0),
        ),
      ),
    );
  }
}

这里是定义提供者的地方:

class QuotesRepository with ChangeNotifier {
  String? lastMessage;

  QuotesRepository.instance();

  Future<void> loadJson(int index) async {
    String data = await rootBundle.loadString('assets/quotes.json');
    Map<String, dynamic> userMap = jsonDecode(data);

    this.lastMessage = userMap['quotes'][index]['quote'];
  }

  Future<void> showScheduledNotification() async {
    int randomValue = 42;
    await loadJson(randomValue).then((value) => showNotificationBody());

    notifyListeners();
  }

  Future<void> showNotificationBody() async {
    FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
        FlutterLocalNotificationsPlugin();
    print("Function called");
    const androidPlatformChannelSpecifics = AndroidNotificationDetails(
      'channel id',
      'channel name',
      'channel description',
      icon: 'flutter_devs',
      largeIcon: DrawableResourceAndroidBitmap('flutter_devs'),
    );

    var iOSPlatformChannelSpecifics = IOSNotificationDetails();
    const NotificationDetails platformChannelSpecifics = NotificationDetails(
      android: androidPlatformChannelSpecifics,
    );
    flutterLocalNotificationsPlugin.periodicallyShow(0, '365<3',
        this.lastMessage, RepeatInterval.everyMinute, platformChannelSpecifics,
        payload: this.lastMessage);
  }
}

然而,这每秒钟都会调用该函数,并导致应用程序崩溃。我知道这是因为我调用quote.showScheduledNotification();notifyListeners()将导致它进入无限循环。
但是如何防止这种情况呢?如何只加载一次,然后在每次通知到达时更新lastMessage
为了简单起见,我每次都给出相同的引文(42)。

qmelpv7a

qmelpv7a1#

看起来你正在寻找一个init函数。如果你把MyApp转换成一个有状态的小部件,你将能够使用stateful小部件的init方法。这应该可以解决问题的一部分。你几乎不应该在build函数中使用init函数,因为它会被频繁地调用。

class MyApp extends StatefulWidget {
  const MyApp();

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    var quote = Provider.of<QuotesRepository>(context);
    quote.showScheduledNotification();
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: new AppBar(
        backgroundColor: Colors.red,
        title: new Text('Flutter notification demo'),
      ),
      body: new Center(
        child: Text(
          Provider.of<QuotesRepository>(context).lastMessage.toString(),
          style: GoogleFonts.clickerScript(fontSize: 40.0),
        ),
      ),
    );
  }
}

PS:关于如何提高应用性能的更多提示,我在my blog上写了一篇文章。

相关问题