Flutter StreamProvider<List<DogModel>> 无法分配

Flutter StreamProvider<List<DogModel>> can't be assigned

我收到以下错误 The argument type 'StreamProvider<List<DogModel>>' can't be assigned to the parameter type 'Stream<List<DogModel>>?'

当我尝试设置流时出现问题 stream: stream,

这里是小部件状态下的流

final stream = StreamProvider<List<DogModel>>(
create: (context) =>
    DogFirestoreService().getDogs('GeVnAbdq9BWs1STbytlAU65qkbc2'),
initialData: const [],

);

小部件构建

Widget build(BuildContext context) {
//final test = context.watch<List<DogModel>>();
//print(test);
return SizedBox(
  width: MediaQuery.of(context).size.width,
  child: StreamBuilder<List<DogModel>>(
    stream: stream,
    builder: (context, snapshot) {
      if (!snapshot.hasData) {
        return const Text('no data');
      }

      if (snapshot.hasError) {
        return const Text('error');
      }

      if (snapshot.hasData) {
        return SizedBox(
          width: double.infinity,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Padding(
                padding: const EdgeInsets.only(
                  top: 65.0,
                  left: 18.0,
                  right: 18.0,
                ),
                child: Text(
                  dogsCount(value.dogsList.length),
                  style: AppStyles.listsHeaderTextStyle,
                ),
              ),
              ListView.builder(
                padding: const EdgeInsets.only(
                  top: 5,
                  bottom: 20,
                  left: 15,
                  right: 15,
                ),
                shrinkWrap: true,
                physics: const NeverScrollableScrollPhysics(),
                itemCount: value.dogsList.length,
                itemBuilder: (context, index) => DogProfileCardWidget(
                  dogInfo: value.dogsList[index],
                  editProfile: openProfileScreen,
                  dogIndex: index,
                ),
              ),
            ],
          ),
        );
      }
      return const Text('data');
    },
  ),
);

} }

你的问题是 stream 变量是 StreamProvider.

StreamProvider 不是 Stream,而是 Widget。所以StreamBuilder没看懂是什么

相反,您可能想这样做:


class Example extends StatefulWidget {
  const Example({Key? key}) : super(key: key);

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

class _ExampleState extends State<Example> {
  // The stream needs to be stored in a StatefulWidfet
  // as you shouldn't create a new stream when the widget rebuild
  final stream = DogFirestoreService().getDogs('GeVnAbdq9BWs1STbytlAU65qkbc2');

  @override
  Widget build(BuildContext context) {
    return StreamBuilder<List<Dog>>(
      stream: stream,
      builder: ...,
    );
  }
}

您不需要 StreamBuilder,因为您正在使用 StreamProvider。此外,在您的代码中,您将 StreamProvider 放在哪里并不明显。顺便说一句,它是一个小部件,因此它应该位于示例中显示的小部件树上方。我看到您将其分配给 final stream = ...,但我不确定为什么,因为它没有 return 流。

StreamProvider 将订阅您提供的流(即 DogFirestoreService().getDogs('...')),一旦数据到达,它就会沿着树向您提供(最初,它会提供initialData).

我在 DartPad 上做了一个简单的例子,你可以在这里查看: Stream Provider Example.

StreamProvider 小部件放在感兴趣的小部件上方后,在 build 方法中,您可以像这样直接访问数据:

final data = context.watch<List<DogModel>>();

在第一个构建中,你会得到你给 StreamProviderinitialData,这是一个空列表。所以你可以这样做:

@override 
build(BuildContext context) {
  final data = context.watch<List<DogModel>>();
  if (data.isEmpty) {
     return const Text('no data');
  } 
  
  return SizedBox(/* the rest of your code */);
}