我有一个流构建器正在侦听Firestore,并且在获取数据时它可以工作。问题是当我切换页面时,streambuilder会不断重建。主页首先构建两次,当我滚动到另一个页面时,它将再次构建两次,当我弹出回到主页时,它将第三次构建,依此类推。图像存储在临时存储器中,我使用AssetImage()打开它们
我的意思是:https://imgur.com/WMzzb0W
如果您需要参考,请按照以下教程操作: https://www.youtube.com/watch?v=8PfiY0U_PBI
代码:
void queryItems() async {
//!Fetch items
try {
Query query = await
yogurts.collection('current_items').where("available", isEqualTo: true);
//!Filter available izdelke
//*QuerySnapshot contains zero or more QueryDocumentSnapshot objects representing the results of a query
items = query.snapshots().map((list) {
//!Convert stream to map on the fly ->
return list.documents.map((doc) {
//*For every document
return doc.data; //*Data from every document
});
});
_postStreamController.add(items);
} catch (e) {
print("Got error: ${e.error}");
}
}
Container buildSelection(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height * 0.9, //!Višina containerja je 90% višine ekrana
decoration: new BoxDecoration(
boxShadow: [
new BoxShadow(
color: Colors.black.withOpacity(0.6), //*Black shadow okoli
offset: new Offset(1.0, 2.0), //*z offsetom
blurRadius: 15.0,
)
],
color: THEME_COLOR.withOpacity(0.9), //*Tema
borderRadius: new BorderRadius.only(
//*Oglati robovi
bottomLeft: const Radius.circular(55.0),
bottomRight: const Radius.circular(55.0))),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
//!Vrsta za orders in settings icone
padding: const EdgeInsets.only(left: 20, right: 20, top: 25),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment
.spaceBetween, //!Porazdeli ikone levo in desno z spaco-om vmes
children: <Widget>[
new OrdersIcon(user: user),
new SettingsIcon(user: user),
],
),
),
//!Stream builder za grajenje seznama izdelkov iz baze
StreamBuilder(
//!Posluša in rebuilda seznam for every new event
stream: items, //?single-subscription stream from the future
initialData: [],
builder: (context, AsyncSnapshot snap) {
//*Rebuilds its childer whenever a new value gets emited by the stream
List slideList =
snap.data.toList(); //! Convert AsynSnapshot into List
print("Number of all items:" + slideList.length.toString());
if (snap.connectionState == ConnectionState.waiting) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
),
);
} else {
return Container(
height: MediaQuery.of(context).size.height * 0.7,
child: PageView.builder(
onPageChanged: (num) {
print("Current index: " + num.toString());
},
controller: itemView, //!Pass PageView controller
scrollDirection: Axis.horizontal,
itemCount: slideList.length, //!Število elementov je dolžina lista
itemBuilder: (context, int currentIndex) {
//!Build current facing item
bool active = (currentIndex == current_page);
//print(active.toString());
//print("Trenutni index: " + currentIndex.toString() + " Trenutna stran: " + current_page.toString());
//?(Lastnosti izdelka kot Map, bool trenutno aktiven, trenutni facing element)
return buildProductListPage(slideList[currentIndex], active, currentIndex);
},
),
);
}
},
),
],
),
);
}
//!Build list view of products
Widget buildProductListPage(Map data, bool active, var index) {
final double blur = active ? 5 : 0;
final double offset = active ? 2 : 0;
final double top = active ? 30 : 200;
final double iconSize = active ? 50 : 0;
final String ime = data['file_name'];
final String path = "${dir.path}/$ime";
print(path);
return AnimatedContainer(
height: 600,
width: 400,
duration: Duration(milliseconds: 1200),
curve: Curves.easeOutQuint,
margin: EdgeInsets.only(top: top, bottom: 10, right: 15, left: 15),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20.0),
image: DecorationImage(
fit: BoxFit.cover, image: AssetImage(path)),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.7),
offset: new Offset(offset / 2, offset),
blurRadius: blur,
)
]),
child: Stack(
children: <Widget>[
Column(
children: <Widget>[
Align(
alignment: Alignment.topCenter,
child: Padding(
padding: const EdgeInsets.only(top: 15.0),
child: Text(
data['ime'],
style: TextStyle(
fontFamily: 'MadeEvolveSans', fontSize: 50, color: WHITE),
),
),
),
Align(
alignment: Alignment.topCenter,
child: Text(
data['volume'].toString() + "ml",
style:
TextStyle(fontFamily: 'MadeEvolveSans', fontSize: 25, color: WHITE),
),
),
],
),
Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0, right: 17.0),
child: IconButton(
onPressed: () {
setState(() {
if (selectedItems.containsKey(data['ime'])) {
selectedItems.update(data['ime'], (dynamic val) => ++val);
} else {
selectedItems[data['ime']] = 1;
}
print(selectedItems);
});
},
icon: Icon(
Icons.add_circle,
color: WHITE,
size: iconSize,
),
),
),
),
Align(
alignment: Alignment.bottomCenter,
child: Padding(
padding: const EdgeInsets.only(bottom: 0.0),
child: Text(
(selectedItems[data['ime']] == 0 || selectedItems[data['ime']] == null)
? " "
: selectedItems[data['ime']].toString(),
style:
TextStyle(fontFamily: 'MadeEvolveSans', fontSize: 60, color: WHITE),
),
),
),
Align(
alignment: Alignment.bottomLeft,
child: Padding(
padding: const EdgeInsets.only(bottom: 15.0, left: 0.0),
child: IconButton(
onPressed: () {
setState(() {
if (selectedItems.containsKey(data['ime'])) {
selectedItems.update(data['ime'], (dynamic val) => --val);
if (selectedItems[data['ime']] == 0) {
selectedItems.remove(data['ime']);
}
}
print(selectedItems);
});
},
icon: Icon(
Icons.do_not_disturb_on,
color: WHITE,
size: iconSize,
),
),
),
),
],
),
);
}
任何帮助将不胜感激:D