[英]Flutter - Provider - How to change UI based on value from Provider?
I want to have two forms of the UI based on an object value that I get from a Stream Provider.我想要基于从 Stream 提供程序获得的 object 值的 UI 的两个 forms。
In the widget, I get the object like this:在小部件中,我得到这样的 object:
final recentPostData = Provider.of<List<RecentPostData>>(context) ?? [];
Then, I want to change the UI based on an attribute of RecentPostData:然后,我想根据RecentPostData的一个属性来改变UI:
return SingleChildScrollView(
child: Column(children: [
(recentPostData[0].attribute != '123') ?
RaisedButton( ... )
: SizedBox( ... ),
The problem: There is a delay of the stream value coming in, thus I get the initial error: "RangeError (index): Invalid value: Valid value range is empty: 0"问题: stream 值有延迟,因此我收到初始错误:“RangeError (index): Invalid value: Valid value range is empty: 0”
I tried to therefore use multiple conditions - hence check first (recentPostData,= []) and then check for the second condition.因此,我尝试使用多个条件 - 因此首先检查 (recentPostData,= []),然后检查第二个条件。 but this did not work (got the same error).
但这不起作用(得到了同样的错误)。
Do you have any idea how to solve this?你知道如何解决这个问题吗?
Many thanks in advance!提前谢谢了!
class _PostFeedState extends State<PostFeed> {
bool isLoading = false; // track if products fetching
@override
Widget build(BuildContext context) {
var recentPostData = Provider.of<List<RecentPostData>>(context) ?? [];
getProducts() async {
if (!hasMore) {
print('No More Products');
return;
}
if (isLoading) {
return;
}
setState(() {
isLoading = true;
});
QuerySnapshot querySnapshot;
if (lastDocument == null) {
querySnapshot = await firestore
.collection('posts')
.orderBy('timestamp', descending: true)
.limit(documentLimit)
.getDocuments();
print(0);
} else {
querySnapshot = await firestore
.collection('posts')
.orderBy('timestamp', descending: true)
.startAfterDocument(lastDocument)
.limit(documentLimit)
.getDocuments();
print(1);
}
if (querySnapshot.documents.length < documentLimit) {
hasMore = false;
}
if (querySnapshot.documents.length == 0) {
setState(() {
hasMore = false;
isLoading = false;
});
return;
}
lastDocument = querySnapshot.documents[querySnapshot.documents.length - 1];
products.addAll(querySnapshot.documents);
setState(() {
isLoading = false;
});
}
if (init) {
getProducts();
setState(() {
init = false;
});
}
void loadNewPosts() {
setState(() {
products = [];
lastDocument = null;
});
getProducts();
}
return SingleChildScrollView(
child: Column(children: [
(recentPostData != []) ? (recentPostData[0].pid != DatabaseServicePosts().postDataFromSnapshot(products[0]).pid) ?
RaisedButton(
onPressed: () {
loadNewPosts();
setState(() {
hasNew = false;
});
},
child: Text('New Posts Available'),
color: Colors.green[300],
)
: SizedBox(height: 0) : SizedBox(height: 0),
products.length == 0
? Center(
child: Text('No Data...'),
) :
Column(children: <Widget>[
...products.map((el) => PostTile (postData: DatabaseServicePosts().postDataFromSnapshot(el))),
],),
(hasMore && !init) ?
RaisedButton(
onPressed: () {
getProducts();
},
child: Text(
'More Posts',
style: TextStyle(color: Colors.white),
),
color: Colors.lightBlue[200],
shape: RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(102.0),
side: BorderSide(color: Colors.blueGrey[400])
),
)
: Padding(
padding: const EdgeInsets.all(10.0),
child: Container(child: Text('No more Posts')),
),
isLoading
? Container(
child: Text('Loading'),
)
: Container(),
SizedBox(height: 10),
]
),
);
}
}
I think before building widget checking size of recentPostData can solve your issue.我认为在构建小部件之前检查 recentPostData 的大小可以解决您的问题。 Following code may help You.
以下代码可能会对您有所帮助。
recentPostData.length > 0 ? (recentPostData[0].attribute != '123') ?
RaisedButton( ... )
: SizedBox( ... ) : Text(" show Loading indicator")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.