Оператор Flutter / Firebase — If / Else возвращает центральный виджет только на долю секунды

#flutter #dart

#флаттер #dart

Вопрос:

Я пытаюсь загрузить данные из firebase. Чтобы обработать событие отсутствия возвращаемых данных, я реализовал оператор if / else . Когда я ожидаю, что данные не будут возвращены, текстовый виджет (вложенный в центральный виджет) отображается на долю секунды (<1 секунды), а затем исчезает. Есть идеи, почему это может происходить? Вот мой код:

     class ProductListPage extends StatelessWidget {
  String event;

  ProductListPage({this.event});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.deepPurpleAccent,
        title: Text(
          " Cards",
          style: TextStyle(color: Colors.white),
        ),
      ),
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('products')
            .where('event', isEqualTo: event)
            .snapshots(),
        builder: buildProductList,
      ),
    );
  }
}

Widget buildProductList(
    BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
  if (snapshot.hasData) {
    return GridView.builder(
        gridDelegate:
        SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        shrinkWrap: true,
        itemCount: snapshot.data.docs.length,
        itemBuilder: (context, index) {
          return Container(
            height: 25.0,
            width: 25.0,
            child:  Image(image: FirebaseImage(snapshot.data.docs[index]['imgUrl'], maxSizeBytes: 15 * 1024 * 1024)));
        });
  } else {
    // Still loading
    return Center(
      child: Text('Something went wrong'),
    );
  }
}
  

Ответ №1:

Да, потому snapshot.hasData что возвращает true только в том случае, если есть только данные, но false во время загрузки или ошибки, поэтому вы видите текст, потому что данные загружаются, лучше переместить и вернуть Text('Something went wrong') snapshot.hasError , иначе верните loader

 Widget buildProductList(
    BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
  if (snapshot.hasData) {
    return GridView.builder(
        gridDelegate:
        SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        shrinkWrap: true,
        itemCount: snapshot.data.docs.length,
        itemBuilder: (context, index) {
          return Container(
            height: 25.0,
            width: 25.0,
            child:  Image(image: FirebaseImage(snapshot.data.docs[index]['imgUrl'], maxSizeBytes: 15 * 1024 * 1024)));
        });
  } else if(snapshot.hasError) {
    // Something is wrong
    return Center(
      child: Text('Something went wrong'),
    );
  }else{
    // Still loading
    return Center(
       child: CircularProgressIndicator(),
    );
  }
}
  

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

1. Спасибо за этот ikerfah, у меня все та же проблема с исчезновением центрального виджета. Я пробовал, если (снимок. data == null) в качестве условия, потому что я думаю, что ошибки нет, просто данные не возвращаются, и это не решило проблему. Есть еще мысли?

2. Не могли бы вы обновить код, который вы используете сейчас?

3. Спасибо за вашу помощь, мне удалось найти решение.

Ответ №2:

Удалось решить проблему, переписав мой код следующим образом:

 class ProductListPage extends StatelessWidget {
  String event;

  ProductListPage({this.event});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.deepPurpleAccent,
        title: Text(
          " Cards",
          style: TextStyle(color: Colors.white),
        ),
      ),
      body: StreamBuilder(
        stream: FirebaseFirestore.instance
            .collection('products')
            .where('event', isEqualTo: event)
            .snapshots(),
        builder: buildProductList,
      ),
    );
  }
}
Widget buildProductList(
    BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
  if (snapshot.hasData) {
    if(snapshot.data.docs.length == 0) {
      return Center(
        child: Text('Something went wrong'),
      );
    } else{
    return GridView.builder(
        gridDelegate:
        SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 2),
        shrinkWrap: true,
        itemCount: snapshot.data.docs.length,
        itemBuilder: (context, index) {
          return Container(
              height: 25.0,
              width: 25.0,
              child:  Image(image: FirebaseImage(snapshot.data.docs[index]['imgUrl'], maxSizeBytes: 15 * 1024 * 1024)));
        });
  }}else{
    // Still loading
    return Center(
      child: CircularProgressIndicator(),
    );
  }
}