Не удается получить аргументы для PushNamed (всегда возвращает значение Null)

# #firebase #flutter #firebase-cloud-messaging

Вопрос:

Я пытался получить аргументы, когда нажимал на уведомление.

Структура является :

  • Облачные сообщения Firebase отправляют уведомление с именем маршрута и другими значениями.
     await _notificationsPlugin.show(
            id,
            message.notification!.title,
            message.notification!.body,
            notificationDetails,
            payload: json.encode(message.data),
          );
 
  • Я добавляю имя пользователя при выборе уведомления.
 _notificationsPlugin.initialize(initializationSettings,
        // ignore: avoid_types_on_closure_parameters
        onSelectNotification: (String? payload) async {
      final args = json.decode(payload!);
      if (args.route != null) {
        Navigator.pushNamed(context, args.route,
            arguments: 'data');
      }
    });
 
  • И с помощью общего маршрута а попытался получить эти аргументы. Я получаю название маршрута, но ничего не аргументирую… Я попробовал со строкой, int, объектом.. ничего не меняется. Аргументы всегда равны нулю
 class AppRouter {
  Route? onGenerateRoute(RouteSettings settings) {
    print('${settings.arguments}'); // always Null

    switch (settings.name) {
      case '/home':
        return MaterialPageRoute(
          builder: (_) => BlocProvider<HomeBloc>(
            create: (context) => getIt<HomeBloc>()
              ..add(GetInfos(data: settings.arguments)),
            child: HomePage(data: settings.arguments),
          ),
        );
      default:
        return null;
    }
  }
}
 

Обновить

Я обновил свой код для передачи настроек в MaterialPageRoute и получения аргументов с помощью ModalRoute, но он не работает.. он всегда равен нулю…

 class AppRouter {
  Route? onGenerateRoute(RouteSettings settings) {
    switch (settings.name) {
      case '/home':
        return MaterialPageRoute(settings: settings, builder: (_) => Screen());
      default:
        return null;
    }
  }
}
 
 class Screen extends StatelessWidget {
  const Screen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final dynamic args = ModalRoute.of(context)!.settings.arguments;
    print(args); // always Null

    return BlocProvider<HomeBloc>(
      create: (context) => getIt<HomeBloc>()
        ..add(GetInfos(data: args)),
      child: HomePage(data: args),
    );
  }
}
 

Ответ №1:

В onGenerateRoute , передайте полученные настройки маршрута при создании MaterialPageRoute :

 settings: settings,
 

После этого в виджете, который вы установили child , например HomePage , как, вы можете получить доступ к аргументам, переданным с pushNamed помощью like (вам нужен контекст have).:

 final dynamic args = ModalRoute.of(context)!.settings.arguments;
 

РЕДАКТИРОВАТЬ: Пожалуйста, найдите ниже минимальный рабочий пример передачи аргументов с onGenerateRoute помощью другого экрана и извлечения его оттуда:

 import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(onGenerateRoute: (settings) {
      switch (settings.name) {
        case '/':
          return MaterialPageRoute(builder: (context) => const MyHome());
        case 'myscreen':
          return MaterialPageRoute(
              builder: (context) => const MyScreen(), settings: settings);
      }
    });
  }
}

class MyHome extends StatelessWidget {
  const MyHome({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('MyHome'),
        ),
        body: Center(
            child: ElevatedButton(
                child: const Text('Go to MyScreen with argument: "hello"'),
                onPressed: () => Navigator.pushNamed(context, 'myscreen',
                    arguments: 'hello'))));
  }
}

class MyScreen extends StatelessWidget {
  const MyScreen({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    final args =
        ModalRoute.of(context)!.settings.arguments ?? 'no argument given';
    print(args);
    return Scaffold(
      appBar: AppBar(
        title: const Text('MyScreen'),
      ),
      body: Center(child: Text(args as String)),
    );
  }
}
 

Комментарии:

1. Ваше решение не работает… Я обновляю свой вопрос этим новым кодом, и да.. аргументы всегда возвращают значение null…, у вас есть другая идея по моей проблеме ?

2. Итак, в AppRouter классе onGenerateRoute функция: является settings.name «домашней» и settings.arguments равна нулю? А args.route в onSelectNotification — это тоже «дом»?

3. Да, именно так, аргс.маршрут и settings.name верните «домой», но параметр settings.arguments равен нулю

4. Я действительно не понимаю, почему это не работает. Я добавлю минимальный, воспроизводимый пример к своему ответу, реализуя то, что я написал ранее, может быть, это поможет.