提供程序不使用Flutter中的提供程序包通知侦听器

时间:2020-07-19 00:10:39

标签: flutter

我正在尝试使用flutter和Marvel API创建一个简单的英雄个人资料应用程序。对于状态管理,我使用提供程序包和带流的bloc策略。 我创建了一个小部件,该小部件是我的搜索栏,用户将在其中输入英雄的名字,每当用户单击“提交”按钮或提交表单时,便在其中添加了对CharacterProfileFormProvider queryCharacter方法的调用。在queryCharacter方法中,调用访问API并返回英雄的服务类。

通话代码:

onFieldSubmitted: (value) async {
            if (_formKey.currentState.validate()) {
              await characterProfileFormProvider
                  .queryCharacter(characterNameController.text);
            }
          }

queryCharacter方法的代码:

queryCharacter(String characterName) async {
    Character character = await characterService.show(characterName);
    characterProfileProvider.changeCharacter(character);
  }

API调用的代码:

Future<Character> show(String characterName) async {
    String url = this.baseUrl + '/$resource';

    Map<String, dynamic> query = this.makeQueryParams();

    query['name'] = characterName;

    Character character;

    try {
      Response response = await Dio().get(url, queryParameters: query);

      character = Character.fromJson(jsonDecode(response.toString()));
    } catch (e) {
      character = Character(
        id: 1009368,
        name: 'Iron Man Test',
        description:
            "Wounded, captured and forced to build a weapon by his enemies, billionaire industrialist Tony Stark instead created an advanced suit of armor to save his life and escape captivity. Now with a new outlook on life, Tony uses his money and intelligence to make the world a safer, better place as Iron Man.",
        thumbnailPath:
            'http://i.annihil.us/u/prod/marvel/i/mg/9/c0/527bb7b37ff55/standard_xlarge.jpg',
        comics: 2554,
        series: 623,
        stories: 3875,
        events: 31,
      );
    }

    return character;
  }

返回API调用之后,结果将通过changeCharacter方法发送到CharacterProfileProvider,该方法在流中输入新字符并调用notifyListeners()方法。

changeCharacter方法的代码:

changeCharacter(Character character) {
    print(character.name);
    inputCharacter.add(character);
    notifyListeners();
  }

最后在屏幕上,我使用“消费者”小部件来获取新值,以在屏幕上呈现数据

使用数据的屏幕的代码:

import 'package:flutter/material.dart';
import 'package:marvel_api/src/models/Character.dart';
import 'package:marvel_api/src/pages/CharacterProfile/CharacterProfileProvider.dart';
import 'package:marvel_api/src/components/CharacterProfileForm/CharacterProfileForm.dart';
import 'package:provider/provider.dart';
import 'package:marvel_api/src/components/ImageResolver/ImageResolver.dart';

class CharacterProfile extends StatefulWidget {
  @override
  _CharacterProfileState createState() => _CharacterProfileState();
}

class _CharacterProfileState extends State<CharacterProfile> {
  final TextStyle numberTitleStyle = TextStyle(
    color: Colors.grey[300],
    fontSize: 24.0,
  );

  final TextStyle numberValueStyle = TextStyle(
    color: Colors.white,
    fontWeight: FontWeight.bold,
    fontSize: 19.0,
  );

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.red,
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 8.0),
            child: Column(
              children: <Widget>[
                // Search Hero
                Expanded(
                  child: CharacterProfileForm(),
                  flex: 1,
                ),
                Expanded(
                  flex: 8,
                  child: Consumer<CharacterProfileProvider>(
                      builder: (context, characterProfileProvider, widget) {
                    return StreamBuilder<Character>(
                        stream: characterProfileProvider.outputCharacter,
                        initialData: Character(),
                        builder: (context, snapshot) {
                          print('Rebuild');
                          return SingleChildScrollView(
                            child: Padding(
                              padding:
                                  const EdgeInsets.symmetric(horizontal: 8.0),
                              child: Column(
                                children: <Widget>[
                                  // Hero Thumbnail
                                  Container(
                                    child: Padding(
                                      padding: EdgeInsets.only(bottom: 15.0),
                                      child: ImageResolver(
                                        image: snapshot.data.thumbnailPath,
                                      ),
                                    ),
                                  ),
                                  // Hero Info
                                  Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    children: <Widget>[
                                      // Character Name:
                                      Text(
                                        'Name:',
                                        style: TextStyle(
                                          color: Colors.grey[300],
                                          fontSize: 28.0,
                                        ),
                                      ),
                                      Text(
                                        snapshot.data.name,
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 22.0,
                                          fontWeight: FontWeight.bold,
                                        ),
                                      ),
                                      SizedBox(
                                        height: 7.0,
                                      ),

                                      // Character Description:
                                      Text(
                                        'Description:',
                                        style: TextStyle(
                                          color: Colors.grey[300],
                                          fontSize: 28.0,
                                        ),
                                      ),
                                      Text(
                                        snapshot.data.description,
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 22.0,
                                          fontWeight: FontWeight.bold,
                                        ),
                                      ),
                                      SizedBox(
                                        height: 7.0,
                                      ),

                                      // Number of comics
                                      Text(
                                        'Number of comics:',
                                        style: numberTitleStyle,
                                      ),
                                      Text(
                                        '$snapshot.data.comics',
                                        style: numberValueStyle,
                                      ),
                                      SizedBox(
                                        height: 8.0,
                                      ),

                                      // Number of series
                                      Text(
                                        'Number of series:',
                                        style: numberTitleStyle,
                                      ),
                                      Text(
                                        '$snapshot.data.series',
                                        style: numberValueStyle,
                                      ),
                                      SizedBox(
                                        height: 8.0,
                                      ),

                                      // Number of stories
                                      Text(
                                        'Number of stories:',
                                        style: numberTitleStyle,
                                      ),
                                      Text(
                                        '$snapshot.data.stories',
                                        style: numberValueStyle,
                                      ),
                                      SizedBox(
                                        height: 8.0,
                                      ),

                                      // Number of events
                                      Text(
                                        'Number of events:',
                                        style: numberTitleStyle,
                                      ),
                                      Text(
                                        '$snapshot.data.events',
                                        style: numberValueStyle,
                                      ),
                                      SizedBox(
                                        height: 8.0,
                                      ),
                                    ],
                                  ),
                                ],
                              ),
                            ),
                          );
                      });
                  }),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

这是我放置提供程序声明的地方:

import 'package:flutter/material.dart';
import 'package:marvel_api/src/pages/CharacterProfile/CharacterProfile.dart';
import 'package:marvel_api/src/pages/CharacterProfile/CharacterProfileProvider.dart';
import 'package:marvel_api/src/components/CharacterProfileForm/CharacterProfileFormProvider.dart';
import 'package:provider/provider.dart';

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(
          create: (_) => CharacterProfileFormProvider(),
        ),
        ChangeNotifierProvider(
          create: (_) => CharacterProfileProvider(),
        ),
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: CharacterProfile(),
      ),
    );
  }
}

此外,所有provider类都从ChangeNotifier类扩展而来。

我的问题是,当调用notifyListener方法时,不会重建侦听器,我使用VS Code调试器确认了这一点,并且尝试使用Provider.of()来获得相同的结果。有人可以帮我还是告诉我我哪里错了。

0 个答案:

没有答案