从列表创建流以构建卡片

时间:2021-01-22 16:07:50

标签: flutter dart flutter-layout flutter-dependencies


我正在创建一个家用汽车应用程序。我的数据库(实时数据库)中存储了几个按钮数据。在我的主页中,我创建了一个 StreamBuilder 以在创建按钮或输入或离开任何类型的数据时进行监听。

我目前的 StreamBuilder 有问题,我无法在主页上访问它的数据,当我尝试打印 snapshot.data 时,我得到 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 个,依此类推: App

1 个答案:

答案 0 :(得分:0)

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

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()。尝试将您的代码与此模式匹配。