Flutter: скрыть или отобразить дочерний виджет, используя выражение из логических значений из firebase firestore

#firebase #flutter

#firebase #flutter

Вопрос:

Я пытался установить логическое выражение для отображения или скрытия текстового виджета, получая оператор true или false из firebase. Вот код и то, что я пробовал. Строка firebase читает Product On-Sale: true (логическое значение).

 import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
// import 'package:productScreen.dart';
// import 'package:resources/app_data.dart';

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder(
          stream: Firestore.instance.collection(appProducts).snapshots(),
          // ignore: missing_return
          builder: (context, snapshot) {
            if (!snapshot.hasData) {
              return Center(
                  child: CircularProgressIndicator(
                      valueColor: AlwaysStoppedAnimation<Color>(
                          Theme.of(context).primaryColor)));
            } else {
              final int dataCount = snapshot.data.documents.length;
              print("data count $dataCount");
              if (dataCount == 0) {
                print('No data Available');
              } else {
                return CustomScrollView(
                  slivers: <Widget>[
                    SliverGrid(
                      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                        crossAxisCount: 2,
                        mainAxisSpacing: 4.0,
                        crossAxisSpacing: 4.0,
                        childAspectRatio: 0.6,
                      ),
                      delegate: SliverChildBuilderDelegate(
                            (BuildContext context, int index) {
                          final DocumentSnapshot document =
                          snapshot.data.documents[index];

                          return buildProducts(context, index, document);
                        },
                        childCount: dataCount,
                      ),
                    ),
                  ],
                );
              }
            }
          }),
    );
  }
}


// import 'package:pages/productScreen.dart';
class NewProductScreen extends StatefulWidget {
  final String productImage, productTitle, productPrice, productSales;
  final bool  productOnSale;

  const NewProductScreen(
      {Key key,
        this.productImage,
        this.productTitle,
        this.productPrice,
        this.productSales,
        this.productOnSale})
      : super(key: key);

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

int indicatorActive = 0;
int _currentIndex = 0;
int selectedSizeIndex = 0;
int selectedColorIndex = 0;

class _NewProductScreenState extends State<NewProductScreen> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: StreamBuilder(
            stream: Firestore.instance.collection(appProducts).snapshots(),
            // ignore: missing_return
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return Center(
                    child: CircularProgressIndicator(
                        valueColor: AlwaysStoppedAnimation<Color>(
                            Theme.of(context).primaryColor)));
              } else {
                final int dataCount = snapshot.data.documents.length;
                print("data count $dataCount");
                if (dataCount == 0) {
                  print('No data Available');
                } else {
                  return CustomScrollView(
                    slivers: <Widget>[
                      SliverGrid(
                        gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                          crossAxisCount: 2,
                          mainAxisSpacing: 4.0,
                          crossAxisSpacing: 4.0,
                          childAspectRatio: 0.6,
                        ),
                        delegate: SliverChildBuilderDelegate(
                              (BuildContext context, int index) {
                            final DocumentSnapshot document =
                            snapshot.data.documents[index];

                            return buildProducts(context, index, document);
                          },
                          childCount: dataCount,
                        ),
                      )
                    ],
                  );
                }
              }
            }));
  }
}


Widget buildProducts(
    BuildContext context, int index, DocumentSnapshot document) {
  List productImage = document[pImages] as List;
  bool onSales = document[pOnSale];
  onSales = false;



  return GestureDetector(
    onTap: () {
      Navigator.push(
          context,
          MaterialPageRoute(
              builder: (context) => NewProductScreen(
                productImage: document[pImages],
                productTitle: document[pTitle],
                productSales: document[pSalesPrice],
                productPrice: document[pPrice],
                productOnSale: document[pOnSale],
              )));
    },
    child: Card(
      elevation: 3,
      child: ClipRRect(
        borderRadius: BorderRadius.circular(5),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Container(
              height: MediaQuery.of(context).size.height / 3.5,
              width: MediaQuery.of(context).size.width / 2,
              decoration: BoxDecoration(
                  image: DecorationImage(image: NetworkImage(productImage[0]))),
            ),
            Expanded(
              flex: 1,
              child: Center(
                child: Container(
                  padding: EdgeInsets.only(top: 5),
                  height: MediaQuery.of(context).size.height / 10,
                  child: Text(
                    "${document[pTitle]}",
                    style: TextStyle(
                      color: Colors.black,
                      fontSize: 15,
                      fontWeight: FontWeight.normal,
                    ),
                  ),
                ),
              ),
            ),
            Expanded(
              flex: 1,
              child: Container(
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.baseline,
                  textBaseline: TextBaseline.alphabetic,
                  children: [
                    Padding(
                      padding: const EdgeInsets.only(left: 8),
                      child: Text(
                        "₦${document[pPrice]}",
                        style: TextStyle(
                          fontSize: 20,
                          fontWeight: FontWeight.normal,
                          color: const Color(0xfff08804),
                        ),
                      ),
                    ),
                    SizedBox(
                      height: 5,
                    ),
                    Text(
                      onSales ? "On Sale" : "",
                      style: TextStyle(
                        fontSize: 10,
                        fontWeight: FontWeight.normal,
                        color: Colors.grey,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    ),
  );
}

// import 'package:resources/app_data.dart';
const String appProducts = "appProducts";

const String pTitle = "Product Title";
const String pPrice = "Product Price";
const String pSalesPrice = "Product Sales Price";
const String pImages = "Product Images";
const String pOnSale = "Product OnSale";

  

Поэтому я хочу использовать выражение true или false, чтобы текстовый виджет отображал текст или пустой текст

                   onSales ? "On Sale" : "",
 
  

![1]: https://imgur.com/bI9QGDx «изображение firebase в соответствии с запросом»

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

1. я не вижу никаких проблем с распродажами? «В продаже»: «»,

2. Спасибо @griffins , но он не показывает текстовый виджет.

3. как насчет добавления текста soem здесь при продаже? «В продаже»: «при продаже false», и вы увидите текст, если false

4. Он отображает «при продаже false», но для логического значения в firebase установлено значение true.

5. я дал ответ на ваш вопрос, если это полезно, не забудьте проголосовать

Ответ №1:

поскольку ваше onSales = false; значение here равно false, оно дает ожидаемый результат, чтобы получить bool из firestore из вашего кода, сделайте это get bool value

document[‘yourboolkey’]

затем

 Text(
                     document['yourboolkey'] ? "On Sale" : "",
                      style: TextStyle(
                        fontSize: 10,...
  

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

1. Спасибо, но теперь я получаю сообщение об ошибке «Ошибка утверждения: логическое выражение не должно быть нулевым». Text( document[pOnSale] ? "On Sale" : "", style: TextStyle( fontSize: 10, fontWeight: FontWeight.normal, color: Colors.grey, ),

2. добавьте фотографию вашего документа firebase

3. Я только что добавил изображение моего документа firebase. @griffins

4. посмотрите на изображение, попробуйте использовать фиксированные клавиши, такие как pOnSale ,

5. Вот так — pOnSale ? "On Sale" : "",

Ответ №2:

Я смог решить проблему, создав модель продукта и используя «Поставщиков» для управления состоянием.

 class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider.value(value: ProductProvider.initialize()),
        StreamProvider.value(value: AuthService().user,)
      ],
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        title: "On Sale",
        theme: ThemeData(
            scaffoldBackgroundColor: BGColor,
            accentColor: Colors.white70,

//        home: Wrapper(),
        routes: {
          '/': (context) => Wrapper(),


        },

//      screens.home: Home(),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) {
    final productProvider = Provider.of<ProductProvider>(context);
    return Scaffold(
        appBar: buildGradientAppBar(),
        body: CustomScrollView(
          slivers: <Widget>[
            SliverGrid(
              gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
                crossAxisCount: 2,
                mainAxisSpacing: 4.0,
                crossAxisSpacing: 4.0,
                childAspectRatio: 0.6,
              ),
              delegate: SliverChildBuilderDelegate(
                    (BuildContext context, int index) {
                  return ProductGridCard(product: productProvider.products[index]);
                },
                childCount: productProvider.products.length,
              ),
            ),
          ],
        )
    );
  }
}

class ProductGridCard extends StatelessWidget {
  final ProductModel product;

  const ProductGridCard({Key key, this.product}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) => NewProductScreen(
                )));
      },
      child: Card(
        elevation: 3,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(5),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.stretch,
            mainAxisSize: MainAxisSize.min,
            children: <Widget>[
              Container(
                height: MediaQuery.of(context).size.height / 3.5,
                width: MediaQuery.of(context).size.width / 2,
                decoration: BoxDecoration(
                    image: DecorationImage(image: NetworkImage(product.images[0]))),
              ),
              Expanded(
                flex: 1,
                child: Center(
                  child: Container(
                    padding: EdgeInsets.only(top: 5),
                    height: MediaQuery.of(context).size.height / 10,
                    child: Text(
                      "${product.title}",
                      style: TextStyle(
                        color: Colors.black,
                        fontSize: 15,
                        fontWeight: FontWeight.normal,
                      ),
                    ),
                  ),
                ),
              ),
              Expanded(
                flex: 1,
                child: Container(
                  child: Row(
                    crossAxisAlignment: CrossAxisAlignment.baseline,
                    textBaseline: TextBaseline.alphabetic,
                    children: [
                      Padding(
                        padding: const EdgeInsets.only(left: 8),
                        child: Text(
                          "₦${product.price}",
                          style: TextStyle(
                            fontSize: 20,
                            fontWeight: FontWeight.normal,
                            color: const Color(0xfff08804),
                          ),
                        ),
                      ),
                      SizedBox(
                        height: 5,
                      ),
                      Padding(
                        padding: const EdgeInsets.only(left: 8),
                        child: Text(
                          "${product.price}",
                          style: TextStyle(
                            fontSize: 10,
                            fontWeight: FontWeight.normal,
                            color: Colors.grey,
                          ),
                        ),
                      ),
                      SizedBox(
                        width: 15,
                      ),
                      Text(
                        product.onSale ? 'ON SALE ' : "",
                        style: TextStyle(
                          fontSize: 10,
                          fontWeight: FontWeight.normal,
                          color: Colors.grey,
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}


class ProductServices {
  String collection = "appProducts";
  Firestore _firestore = Firestore.instance;

  Future<List<ProductModel>> getProducts() async =>
      _firestore.collection(collection).getDocuments().then((result) {
        List<ProductModel> products = [];
        for (DocumentSnapshot product in result.documents) {
          products.add(ProductModel.fromSnapshot(product));
        }
        return products;
      });
}

class ProductProvider with ChangeNotifier{
  ProductServices _productServices = ProductServices();
  List<ProductModel> products = [];
  // List<ProductModel> productsSearched = [];


  ProductProvider.initialize(){
    loadProducts();
  }

  loadProducts()async{
    products = await _productServices.getProducts();
    notifyListeners();
  }

}

class ProductModel{
  static const ID = "id";
  static const TITLE = "Product Title";
  static const Images = "Product Images";
  static const PRICE = "Product Price";
  static const SALE = "Product On-Sale";



  String _id;
  String _title;
  List _images;
  String _price;
  bool _onSale;

  String get id => _id;

  String get title => _title;

  List get images => _images;

  String get price => _price;

  bool get onSale => _onSale;
  


  ProductModel.fromSnapshot(DocumentSnapshot snapshot) {
// _id = snapshot.data()[ID];
    _onSale = snapshot.data[SALE];
    _price = snapshot.data[PRICE];
    _title = snapshot.data[TITLE];
    _images = snapshot.data[Images];

  }
}```

Without the product model, the boolean won't be able to get the value of the boolean from firebase. 
         `bool get onSale => _onSale;`