【问题标题】:How to use Streambuilder in flutter如何在 flutter 中使用 Streambuilder
【发布时间】:2022-12-25 19:12:40
【问题描述】:
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';

void main() async {
  //Run this first
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Smart Bin',
      home: new HomePageWidget(),
    );
  }
}

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

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

class _HomePageWidgetState extends State<HomePageWidget> {
  final scaffoldKey = GlobalKey<ScaffoldState>();
  final currentBinRecord = FirebaseFirestore.instance.collection("current_bin");


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: scaffoldKey,
      appBar: AppBar(
        title: Text(
          'SmartBin',
        ),
      ),
      body: SafeArea(
        child: GestureDetector(
          onTap: () => FocusScope.of(context).unfocus(),
          child: Column(
            mainAxisSize: MainAxisSize.max,
            children: [
              Expanded(
                child: StreamBuilder<List<CurrentBinRecord>>(
                  stream: queryCurrentBinRecord(
                    queryBuilder: (currentBinRecord) =>
                        currentBinRecord.orderBy('level', descending: true),
                  ),
                  builder: (context, snapshot) {
                    // Customize what your widget looks like when it's loading.
                    if (!snapshot.hasData) {
                      return Center(
                        child: SizedBox(
                          width: 50,
                          height: 50,
                          child: CircularProgressIndicator(),
                        ),
                      );
                    }
                    List<CurrentBinRecord> listViewCurrentBinRecordList =
                        snapshot.data;
                    return ListView.builder(
                      padding: EdgeInsets.zero,
                      scrollDirection: Axis.vertical,
                      itemCount: listViewCurrentBinRecordList.length,
                      itemBuilder: (context, listViewIndex) {
                        final listViewCurrentBinRecord =
                            listViewCurrentBinRecordList[listViewIndex];
                        return Row(
                          mainAxisSize: MainAxisSize.max,
                          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                          children: [
                            Text(
                              listViewCurrentBinRecord.area,
                            ),
                            Text(
                              listViewCurrentBinRecord.level.toString(),
                            ),
                          ],
                        );
                      },
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

This is the error

第一个错误是:

child: StreamBuilder<List<CurrentBinRecord>>

名称“CurrentBinRecord”不是类型,因此不能用作类型参数。 尝试将名称更正为现有类型,或定义名为“CurrentBinRecord”的类型。

第二个错误是:

stream: queryCurrentBinRecord

未为类型“_HomePageWidgetState”定义方法“queryCurrentBinRecord”。 尝试将名称更正为现有方法的名称,或定义名为“queryCurrentBinRecord”的方法。

第三个错误是:

List<CurrentBinRecord> listViewCurrentBinRecordList =
                        snapshot.data;

名称“CurrentBinRecord”不是类型,因此不能用作类型参数。 尝试将名称更正为现有类型,或定义名为“CurrentBinRecord”的类型。

【问题讨论】:

    标签: android flutter firebase dart google-cloud-firestore


    【解决方案1】:

    这些是语法尝试 -

    return StreamBuilder(
      stream: theStreamSource, // Eg a firebase query
      builder: (context, AsyncSnapshot snapshot) {
        if (!snapshot.hasData) {
           return Center(
             child: CircularProgressIndicator(),
           );
        }
        return ListView.builder(
            itemCount: snapshot.data.documents.length,
            itemBuilder: (context, int index) {
              return Text(snapshot.data.documents[index]['title']);
            }
        );
      },
    );
    

    希望能帮助到你。

    【讨论】:

      【解决方案2】:

      我认为使用 StreamBuilder 的最佳方式是创建单独的控制器类来处理所有业务逻辑并更新 UI。

      // your widget class
      class UIClass extends StatefulWidget {
      
      
        const UIClass({Key key}) : super(key: key);
      
        @override
        _UIClassState createState() => _UIClassState();
      }
      
      class _UIClassState extends State<UIClass> {
      
        UIClassController<List<CurrentBinRecord>> _uiController;
      
        @override
        void initState() {
          _uiController = UIClassController(StreamController<List<CurrentBinRecord>>());
          super.initState();
        }
        @override
        Widget build(BuildContext context) {
          return Column(
            children: [
              Text("Hello Everyone"),
              StreamBuilder<List<CurrentBinRecord>>(
                stream: _uiController.uiStream,
                builder: (context, snapshot) {
                   if(snapshot.hasError){
                     return ErrorWidget();
                   }
                   else if(snapshot.connectionState == ConnectionState.waiting){
                     return WaitingWidget();
                   }
                   else if(snapshot.hasData){
                     return ListView.builder(
                       padding: EdgeInsets.zero,
                       scrollDirection: Axis.vertical,
                       itemCount: snapshot.data.length,
                       itemBuilder: (context, listViewIndex) {
                         final listViewCurrentBinRecord =
                         snapshot.data[listViewIndex];
                         return Row(
                           mainAxisSize: MainAxisSize.max,
                           mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                           children: [
                             Text(
                               listViewCurrentBinRecord.area,
                             ),
                             Text(
                               listViewCurrentBinRecord.level.toString(),
                             ),
                           ],
                         );
                       },
                     );
                   }
                   else{
                     return SizedBox();
                   }
                }
              ),
            ],
          );
        }
      
        @override
        void dispose() {
          super.dispose();
          _uiController.dispose();
        }
      }
      
      
      // controller class to handle all business logic
      // you can also split it into multiple sub controllers
      class UIClassController<T> {
      
        final StreamController<T> _controller;
      
        // If you are using this on multiple widgets then  use asBroadcastStream()
        Stream<T> get uiStream => _controller.stream;
      
        UIClassController(this._controller);
      
        void updateMyUI([dynamic params]){
             T t;
            // your logic //
            //------------//
            _controller.sink.add(t);
        }
      
        void dispose(){
          _controller.close();
        }
      
      }
      

      【讨论】:

        【解决方案3】:

        我用于 StreamBuilder 的代码

                import 'package:cloud_firestore/cloud_firestore.dart';
                import 'package:firebase_auth/firebase_auth.dart';
                import 'package:flutter/material.dart';
                import '../door/widgets/Navbar.dart';
                import '../door/widgets/sidenav.dart';
                import 'package:get/get.dart';
        
                FirebaseAuth auth = FirebaseAuth.instance;
        
                class CartPage extends StatefulWidget {
                  @override
                  _CartPageState createState() => _CartPageState();
                }
        
                class _CartPageState extends State<CartPage> {
                  final FirebaseFirestore fb = FirebaseFirestore.instance;
                  int up = 1;
                  bool loading = false;
                  final ScrollController _scrollController = ScrollController();
        
                  @override
                  void initState() {
                    super.initState();
                    getCartData();
                  }
        
                  void addMore(qty, documentID) {
                    int new_qty = qty + 1;
                    Get.snackbar('Qty! ', new_qty.toString());
                    String collection_name = "cart_${auth.currentUser?.email}";
                    FirebaseFirestore.instance
                        .collection(collection_name)
                        .doc(documentID)
                        .update({
                      'qty': new_qty,
                      'updated_at': Timestamp.now(),
                    }) // <-- Your data
                        .then((_) => print('Added'))
                        .catchError((error) => Get.snackbar('Failed!', 'Error: $error'));
                  }
        
                  void minusMore(qty, documentID) {
                    if (qty > 1) {
                      int new_qty = qty - 1;
                      String collection_name = "cart_${auth.currentUser?.email}";
                      FirebaseFirestore.instance
                          .collection(collection_name)
                          .doc(documentID)
                          .update({
                        'qty': new_qty,
                        'updated_at': Timestamp.now(),
                      }) // <-- Your data
                          .then((_) => print('Subtracted'))
                          .catchError((error) => Get.snackbar('Failed!', 'Error: $error'));
                    }
                  }
        
                  Stream<QuerySnapshot> getCartData() {
                    String collection_name = "cart_${auth.currentUser?.email}";
                    return FirebaseFirestore.instance
                        .collection(collection_name)
                        .orderBy("created_at", descending: false)
                        .snapshots();
                  }
        
                  final ButtonStyle style = ElevatedButton.styleFrom(
                      minimumSize: Size(50, 30),
                      backgroundColor: Color(0xFFFFB61A),
                      elevation: 6,
                      textStyle: const TextStyle(fontSize: 11),
                      shape: const RoundedRectangleBorder(
                          borderRadius: BorderRadius.all(
                            Radius.circular(20),
                          )));
        
                  @override
                  Widget build(BuildContext context) {
                    return Scaffold(
                      appBar: Navbar.navbar(),
                      drawer: Sidenav.sidenav(),
                      body: Container(
                        padding: EdgeInsets.all(10.0),
                        child: StreamBuilder<QuerySnapshot>(
                          stream: getCartData(),
                          builder: (context, snapshot) {
                            switch (snapshot.connectionState) {
                              case ConnectionState.waiting:
                                return Center(child: CircularProgressIndicator());
                              default:
                                if (snapshot.hasError) {
                                  return buildText('Something Went Wrong Try later');
                                } else {
                                  if (!snapshot.hasData) {
                                    return Card(
                                      child: Column(
                                        mainAxisSize: MainAxisSize.min,
                                        children: <Widget>[
                                          ListTile(
                                            leading: ConstrainedBox(
                                              constraints: const BoxConstraints(
                                                minWidth: 100,
                                                minHeight: 190,
                                                maxWidth: 200,
                                                maxHeight: 200,
                                              ),
                                              child: Icon(Icons.shopping_cart, size: 45),
                                            ),
                                            title: Text('No Food!'),
                                            subtitle: const Text('Your cart is empty!'),
                                          ),
                                        ],
                                      ),
                                    );
                                  } else {
                                    return ListView.builder(
                                        physics: const BouncingScrollPhysics(),
                                        shrinkWrap: true,
                                        itemCount: snapshot.data?.docs.length,
                                        itemBuilder: (BuildContext context, int index) {
                                          return SizedBox(
                                            height: 90.0,
                                            child: Card(
                                              elevation: 10,
                                              child: Row(
                                                mainAxisAlignment: MainAxisAlignment.start,
                                                crossAxisAlignment:
                                                CrossAxisAlignment.start,
                                                mainAxisSize: MainAxisSize.max,
                                                children: <Widget>[
                                                  const SizedBox(
                                                    width: 20,
                                                  ),
                                                  _buildImg('assets/logo.png', '60', '60'),
                                                  const SizedBox(
                                                    width: 14,
                                                  ),
                                                  SizedBox(
                                                    width:
                                                    MediaQuery.of(context).size.width *
                                                        0.33,
                                                    child: Column(
                                                      mainAxisSize: MainAxisSize.max,
                                                      crossAxisAlignment:
                                                      CrossAxisAlignment.start,
                                                      children: <Widget>[
                                                        const SizedBox(
                                                          height: 20,
                                                        ),
                                                        Text(
                                                            snapshot.data?.docs[index]
                                                            ["name"],
                                                            maxLines: 2,
                                                            style: const TextStyle(
                                                                fontWeight: FontWeight.w500,
                                                                fontSize: 14)),
                                                        const SizedBox(
                                                          height: 5,
                                                        ),
                                                        Text(
                                                            "₹${snapshot.data?.docs[index]["price"]}",
                                                            style: const TextStyle(
                                                                fontWeight: FontWeight.w400,
                                                                fontSize: 12)),
                                                      ],
                                                    ),
                                                  ),
                                                  const SizedBox(
                                                    width: 10,
                                                  ),
                                                  Container(
                                                    margin: const EdgeInsets.only(
                                                        top: 20.0, bottom: 10.0),
                                                    decoration: BoxDecoration(
                                                        color: const Color(0xFFFFB61A),
                                                        // color: Color(0xFF0A2031),
                                                        borderRadius:
                                                        BorderRadius.circular(17)),
                                                    child: Row(
                                                      mainAxisAlignment:
                                                      MainAxisAlignment.spaceBetween,
                                                      crossAxisAlignment:
                                                      CrossAxisAlignment.end,
                                                      children: <Widget>[
                                                        SizedBox(
                                                          height: 40,
                                                          child: IconButton(
                                                              onPressed: () {
                                                                minusMore(
                                                                    snapshot.data
                                                                        ?.docs[index]
                                                                    ["qty"],
                                                                    snapshot
                                                                        .data
                                                                        ?.docs[index]
                                                                        .reference
                                                                        .id);
                                                              },
                                                              color: Colors.white,
                                                              icon:
                                                              const Icon(Icons.remove)),
                                                        ),
                                                        const SizedBox(
                                                          width: 5,
                                                        ),
                                                        Container(
                                                          margin: const EdgeInsets.only(
                                                              bottom: 10.0),
                                                          child: Text(
                                                              "${snapshot.data?.docs[index]["qty"]}",
                                                              style: const TextStyle(
                                                                  fontWeight:
                                                                  FontWeight.w400,
                                                                  color: Colors.white,
                                                                  fontSize: 16)),
                                                        ),
                                                        const SizedBox(
                                                          width: 5,
                                                        ),
                                                        SizedBox(
                                                          height: 40,
                                                          child: IconButton(
                                                              color: Colors.white,
                                                              onPressed: () {
                                                                addMore(
                                                                    snapshot.data
                                                                        ?.docs[index]
                                                                    ["qty"],
                                                                    snapshot
                                                                        .data
                                                                        ?.docs[index]
                                                                        .reference
                                                                        .id);
                                                              },
                                                              icon: const Icon(Icons.add)),
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                  const SizedBox(
                                                    width: 10,
                                                  ),
                                                ],
                                              ),
                                            ),
                                          );
                                        });
                                  }
                                }
                            }
                          },
                        ),
                      ),
                    );
                  }
        
                  Widget buildText(String text) => Center(
                    child: Text(
                      text,
                      style: TextStyle(fontSize: 24, color: Colors.black),
                    ),
                  );
        
                  _buildImg(img, hei, wid) {
                    return Container(
                      alignment: Alignment.center, // use aligment
                      child: Image.asset(
                        img,
                        height: double.parse(hei),
                        width: double.parse(wid),
                        fit: BoxFit.cover,
                      ),
                    );
                  }
                }
        

        【讨论】:

          猜你喜欢
          • 2019-11-29
          • 2021-05-17
          • 2020-12-11
          • 1970-01-01
          • 2019-12-10
          • 2020-03-12
          • 2021-08-17
          • 2019-10-26
          • 2020-06-25
          相关资源
          最近更新 更多