从列表创建流到构建卡牌



我正在创建一个Home Auto应用程序。我有几个按钮数据存储在我的数据库(实时数据库)。在我的主页上,我创建了一个StreamBuilder,每当有一个按钮创建或任何类型的数据输入或离开时,都可以收听。

我目前有问题与我的StreamBuilder,我无法访问它在主页上的数据,当我尝试打印快照。数据,我得到0作为响应。流是一个列表。这是snapshot.value:

的输出
[{icon: delte, nome: Junior}, {icon: add, nome: Televisao}, {icon: bulb, nome: BAtata}]

这是流:

Stream<List> readData() async*{
Map<dynamic, dynamic> button_list = Map();
var lst = [];
final FirebaseUser user = await _auth.currentUser();
Stream stream = await databaseReference.child(user.uid+"/buttons/").once().then((DataSnapshot snapshot) {
final value = snapshot.value as Map;
lst = value.values.toList();

});
await for(var event in stream) {
yield event.lst;
}
}

我将使用列表中的内容创建按钮。
这是创建卡片的页面:

import 'package:flutter/material.dart';
class CreateCard extends StatelessWidget {
String name;
String icon;
CreateCard(this.name, [this.icon]); //[] para que o icon não seja obrigatorio de colocar
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: (){

},
child: Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(15)
),
child: Stack(
children: [
Positioned(
top: 10,
left: 10,
child: Icon(
icon == null ? Icons.check_box_outline_blank : getIconData(icon),
size: 35,
color: Colors.white,
),
),
Positioned(
top: 95,
left: 15,
child: Text(name, style: TextStyle(color: Colors.white),),
),
],
),
),
);
}
}
IconData getIconData(String name) {
switch (name) {
case "Lock":
return Icons.lock;
case "LightBulb":
return Icons.lightbulb_outline;
case "Check":
return Icons.check;
}
}

这是主界面:

import 'package:automacaoaplicativo/buttons/create_card.dart';
import 'package:flutter/material.dart';
import 'package:automacaoaplicativo/services/auth.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
final AuthService _auth = AuthService();
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey,
appBar: AppBar(
title: Text('Main page'),
actions: <Widget>[
FlatButton.icon(onPressed: () {
_auth.signOut();
}, 
icon: Icon(Icons.logout), 
label: Text('Logout'))
],
),
body: StreamBuilder(
stream: _auth.readData(),
initialData: 0,
builder: (context, snapshot) {
if (snapshot.hasError || snapshot.hasError){
return Container(color: Colors.red);
}
if (!snapshot.hasData || !snapshot.hasData){
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasData || snapshot.hasData){
return GridView.count(
padding: EdgeInsets.all(15),
crossAxisSpacing: 20.0,
mainAxisSpacing: 20.0,
crossAxisCount: 3,
children: [
CreateCard("ola"), // I would need to loop throw this card and 
send the data from readData() on the list format,
CreateCard(snapshot.data[0][0], snapshot.data[0][1]) and so on for position 1, 2, etc
GestureDetector(
onTap: () async{
_auth.readData();
},
child: Container(
color: Colors.black,
width: 150,
height: 150,
child: Icon(Icons.add, color: Colors.white,),

),
),
],
);
}
}
),
);
}
}

这就是应用程序的样子,应该有3个这样的黑盒,因为我有3个来自按钮的数据,如果我有4个,应该有4个,等等:应用

您应该尝试将您的流设计模式与以下内容相匹配:

void main() async {
// This is where you would use a StreamBuilder rather than this use.
await for (var value in getData()) {
print(value);
}

/*
* return StreamBuilder<List>(
*  stream: getData(),
*  builder: (context, snapshot) => YourWidget(snapshot.data);
* );
* */
}
// This is *your* Stream function.
Stream<List> getData() async* {
var list = [];
// Make sure the stream you are wrapping is invokable.
await for (var data in mockRemoteData(10)) {
// this is where you do you data manipulation.
list.add(data);
yield list;
}
}
// Ignore the implmentation, just imagine you are recieving data from a network
// and it just timeouts at some point.
Stream<int> mockRemoteData(int timeout) async* {
int i = 0;
while (true) {
await Future.delayed(const Duration(seconds: 1));
yield i++;
if (i == timeout) break;
}
}

getData()是您要创建的函数。你基本上是包装另一个流,在这个例子中它是mockRemoteData()。尝试将您的代码与此模式匹配。

最新更新