ошибка: Тип аргумента «Объект?» не может быть присвоен типу параметра «Строка»

#flutter #dart

Вопрос:

проблема ясна, я просто не знаю, как ее решить …

вот вся страница :

 import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:provider_practice_part2/controller/user_notifier.dart';
import 'package:provider_practice_part2/models/user.dart';
import 'package:provider_practice_part2/screens/user_list_screen.dart';
import 'package:provider_practice_part2/widgets/cheetah_button.dart';
import 'package:provider_practice_part2/widgets/cheetah_input.dart';
import 'package:provider_practice_part2/widgets/user_list.dart';

class Home extends StatefulWidget {
  @override
  HomeState createState() => HomeState();
}

class HomeState extends State<Home> {
  String? _name;
  String? _city;

  final GlobalKey<FormState> _formKey = GlobalKey<FormState>();

  @override
  Widget build(BuildContext context) {
    UserNotifier userNotifier = Provider.of<UserNotifier>(context);
    return Scaffold(
      backgroundColor: Theme.of(context).backgroundColor,
      appBar: AppBar(
        title: Consumer(
          builder: (context, title, child) {
            return Text(
              title,
              style: TextStyle(color: Colors.white),
            );
          },
        ),
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(32),
        child: Form(
          key: _formKey,
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              CheetahInput(
                labelText: 'Name',
                onSaved: (String? value) {
                  _name = value;
                },
              ),
              SizedBox(height: 16),
              CheetahInput(
                labelText: 'City',
                onSaved: (String? value) {
                  _city = value;
                },
              ),
              SizedBox(height: 20),
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  CheetahButton(
                    text: 'Add',
                    onPressed: () {
                      if (!_formKey.currentState!.validate()) return;

                      _formKey.currentState!.save();
                      context
                          .read<UserNotifier>()
                          .addUser(User(_name!, _city!));
                    },
                  ),
                  SizedBox(width: 8),
                  CheetahButton(
                    text: 'List',
                    onPressed: () {
                      Navigator.push(
                        context,
                        MaterialPageRoute(
                          builder: (context) => UserListScreen(),
                        ),
                      );
                    },
                  ),
                ],
              ),
              SizedBox(height: 20),
              UserList(),
            ],
          ),
        ),
      ),
    );
  }
}
 

проблема в том, что здесь :

 Consumer(
          builder: (context, title, child) {
            return Text(
              title,
              style: TextStyle(color: Colors.white),
            );
          },
        ),
 

как вы можете видеть из заголовка, в нем есть ошибка, когда я пытаюсь передать данные от потребителя в текстовый виджет, я уже пробовал оператор Null_aware и оператор nullable, но он не работает …..
в конце концов, я решил проблему, удалив всего потребителя и заменив его этим кодом :

 Text(
          context.watch<String>(),
          style: TextStyle(color: Colors.white),
        ),
 

я просто хочу знать, есть ли какое-либо решение этой проблемы, мне и другим будущим программистам было бы полезно ознакомиться с этим вопросом .

примечание : я использую провайдера 5 примечание : этот вызов является будущим для некоторых искусственных данных, просто чтобы проверить, как работает futureprovider..

Ответ №1:

Вам просто нужно использовать

 Consumer<String>(
...
)
 

Ответ №2:

Когда вы используете a Consumer , вам нужно передать параметр универсального типа, чтобы класс знал, что вы пытаетесь использовать, точно так же, как и то, что вы делаете context.watch<String>() . Из-за того, как генераторы работают в Dart, если вы не укажете тип, Dart попытается использовать вывод типа для автоматического выбора типа. Но поскольку из тела ничего нельзя сделать Consumer , Dart просто по умолчанию выберет самый базовый тип, который, как оказалось, есть Object? .

Это важно не только для того, чтобы код знал, какой тип title будет, но и потому Consumer , что ему необходимо знать, какой тип искать во всех родительских поставщиках, которые он должен просмотреть, чтобы узнать, какой из них в конечном итоге прослушивать.

 Consumer<String>(
  builder: (context, title, child) {
    return Text(
      title,
      style: TextStyle(color: Colors.white),
    );
  },
),