#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;`