扑火Firebase Streambuilder给出返回的空错误

时间:2020-10-14 03:17:26

标签: flutter google-cloud-firestore stream-builder

我正在尝试通过Flutter从我的Firebase Firestore数据库中实时读取数据。我了解到,管理此问题的最佳方法是streambuilder。检查了有关此主题的几个站点,并编写了如下代码,并添加了一条打印语句,以查看一切是否正常,但是,当我运行该程序时,它却显示出错误提示:

A build function returned null.
The relevant error-causing widget was: 
  StreamBuilder<DocumentSnapshot> file:///C:/Users/faruk/Desktop/3-sayiavi/sayi_avi/lib/gamescreen.dart:116:15

The method '[]' was called on null.
Receiver: null
Tried calling: []("status")
The relevant error-causing widget was: 
  StreamBuilder<DocumentSnapshot> file:///C:/Users/faruk/Desktop/3-sayiavi/sayi_avi/lib/gamescreen.dart:116:15

我的代码如下:

    import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  FirebaseUser loggedInUser;
  final _firestore = Firestore.instance;
  String collectionPath = 'users';
  String docPath;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }
  
  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser();
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
        print(docPath);
        print(collectionPath);
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
      //todo: _auth.signOut(); ekleyerek signout yapacaz
      //Navigator.pop(context); bir önceki ekrana dönecez;
    );
  }





  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder(
          stream: _firestore.collection(collectionPath).document(docPath).snapshots(),
          builder: (context,snapshot){
            if(snapshot.hasData){
              var userDocument = snapshot.data;
              print(userDocument['status']);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}

更改了这样的代码:

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  FirebaseUser loggedInUser;
  final _firestore = Firestore.instance;
  String collectionPath = 'users';
  String docPath;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }

  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser();
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
        print(docPath);
        print(collectionPath);
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
      //todo: _auth.signOut(); ekleyerek signout yapacaz
      //Navigator.pop(context); bir önceki ekrana dönecez;
    );
  }





  @override
  Widget build(BuildContext context) {

    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder<DocumentSnapshot>(
          stream: _firestore.collection(collectionPath).document(docPath).snapshots(),
          builder: (BuildContext context,AsyncSnapshot<DocumentSnapshot> snapshot){
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Text("Loading");
            }
            if(snapshot.hasData){
              Map<String, dynamic> userDocument  = snapshot.data.data;
              print(userDocument);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}

当前,当我单击“保存”按钮时,它将获取地图的值,但是当我在avd中来回移动时,它将再次为null。有什么问题吗?

我想做的是,有一个firebase函数可以根据用户在数据库中的“状态”来匹配他们。当用户进入此屏幕时,其状态在数据库中将为“ on”,并且当firebase函数找到状态为“ on”的另一个用户时,其状态都将为“ ready”或类似的状态。当用户的状态更改为“就绪”而不是显示例如“正在搜索比赛”屏幕时,它将更改为游戏屏幕,并且将开始播放2 ppl。因此,总结一下,只要用户进入此屏幕,它就应该开始侦听其状态的变化。同样,由于它将是回合制游戏,因此以后应继续侦听其他字段以查找数据库更改。我希望我能自己解释一下。

为下面的新依赖项更新了flutter Firebase代码

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}
class GameScreen extends StatefulWidget {
  static String id ='gamescreen';
  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  final _auth =FirebaseAuth.instance;
  User loggedInUser;
  final _firestore = FirebaseFirestore.instance;
  final String collectionPath = 'users';
  String docPath;
  DocumentReference userdoc;

  @override
  void initState(){
    super.initState();
    getCurrentUser();
  }


  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser;
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
    );
  }




  @override
  Widget build(BuildContext context) {
    userdoc = _firestore.collection(collectionPath).doc(docPath);
    return StreamBuilder<DocumentSnapshot>(
      stream: userdoc.snapshots(),
      builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }
        if(snapshot.hasData){
          Map<String, dynamic> userDocument  = snapshot.data.data();
          print(collectionPath);
          print(docPath);
          print(snapshot.data);
          print(userDocument);
          return MaterialApp(
            home:Scaffold(
              appBar: AppBar(
                backgroundColor: Colors.amberAccent,
                title: Text('Sayı Avı Oyun Ekranı'),
              ),
              body:Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      },
    );
  }
}

您可以看到有4张照片可以检查我是否正确获取了数据。目前,当我运行该应用程序时,它会显示

I / flutter(15703):用户 I /颤振(15703):viPK8SpL9MOIV2bQqGzBkKVdYAk2 I / flutter(15703):“ DocumentSnapshot”的实例 I / flutter(15703):空

当我单击android studio中的“保存”按钮时,第四个应该不为空

I / flutter(15703):用户 I /颤振(15703):viPK8SpL9MOIV2bQqGzBkKVdYAk2 I / flutter(15703):“ DocumentSnapshot”的实例 I / flutter(15703):{密码:123456,失败:0,获胜:0,电子邮件:faruk@durusoy.net,状态:准备就绪}

哪个是正确的结果。

4 个答案:

答案 0 :(得分:0)

您忘记在data()的StreamBuilder中调用snapshots()

var userDocument = snapshot.data.data();

请参阅:https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes

答案 1 :(得分:0)

我认为当您返回上一个屏幕时,initState and getCurrentUser()函数不会再次调用,docPath is null也不会再次调用并获得docPath

答案 2 :(得分:0)

首先,您应该调用initState,然后对其进行处置。因为每次您运行该页面或对其进行更新时,您都会调用initState(),因此您可能会再次丢失所有数据。代码是这样的:

  void initState() {
    super.initState();
   getCurrentUser();
  }

  @override
  void dispose() {
    // : implement dispose
   getCurrentUser();
    super.dispose();
  }

如果那没有帮助阅读此代码。由于QuerySnapshotDocumentSnapShot

,我遇到了这个问题
 StreamBuilder<QuerySnapshot>(

        stream: Firestore.instance.collection("MyTodos").snapshots(),

        builder: (context, snapshots) {

          return ListView.builder(
            shrinkWrap: true,
            addAutomaticKeepAlives: true,
            itemCount: snapshots.data.documents.length,
           
            itemBuilder: (BuildContext context, int index) {

              DocumentSnapshot documentSnapshot =
                  snapshots.data.documents[index];

              return Card(              
                  margin: EdgeInsets.all(6),
                  elevation: 2.0,
                  child: ListTile(
                  title: Text(documentSnapshot.data["todoTitle"]),                     
                  ),               
              );
            },
          );
        },
      ),

根据您的错误。我将您的代码更改为此,您可以在此链接https://firebase.flutter.dev/docs/firestore/usage/#realtime-changes

中找到更多信息
@override
  Widget build(BuildContext context) {
final users = _firestore.collection(collectionPath).document(docPath);
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.amberAccent,
          title: Text('Sayı Avı Oyun Ekranı'),
        ),
        body: StreamBuilder<QuerySnapshot>(
          stream: users.snapshots(),
          builder: (BuildContext context,AsyncSnapshot<QuerySnapshot> snapshot){
            if (snapshot.hasError) {
              return Text('Something went wrong');
            }
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Text("Loading");
            }
            if(snapshot.hasData){
              Map<String, dynamic> userDocument  = snapshot.data.documents;
              print(userDocument);
              return Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              );
            }
          },
        ),
      ),
    );
  }
}

答案 3 :(得分:0)

尝试了ahmed的答案并且没有解决方案后,我决定像这里的https://firebase.flutter.dev/docs/overview那样重新排列我的代码,终于可以了。还升级了我的所有依赖项。

这是我的最终代码:

import 'package:flutter/material.dart';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'numbers.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_core/firebase_core.dart';


Numbers myNumbers = Numbers();

void main(){
  runApp(
      GameScreen()
  );
}

class GameScreen extends StatefulWidget {
  static String id ='gamescreen';

  @override
  _GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
  bool _initialized = false;
  bool _error = false;

  void initializeFlutterFire() async {
    try {
      // Wait for Firebase to initialize and set `_initialized` state to true
      await Firebase.initializeApp();
      setState(() {
        _initialized = true;
      });
    } catch(e) {
      // Set `_error` state to true if Firebase initialization fails
      setState(() {
        _error = true;
      });
    }
  }

  @override
  void initState() {
    initializeFlutterFire();
    super.initState();
    getCurrentUser();
  }

  final _auth =FirebaseAuth.instance;
  User loggedInUser;
  final _firestore = FirebaseFirestore.instance;
  final String collectionPath = 'users';
  String docPath;
  DocumentReference userdoc;


  void getCurrentUser() async{
    try{
      final user = await _auth.currentUser;
      if(user !=null){
        loggedInUser =user;
        docPath = loggedInUser.uid;
      }
    }catch(e){
      print(e);
    }
  }


  Expanded attachNumber(imagenumber){
    return Expanded(
      child:FlatButton(
        onPressed: (){
          setState(() {
            if(!myNumbers.numberStatus[1]){
              myNumbers.buttonValues['numberimage1'] = imagenumber;
              myNumbers.numberStatus[1] =true;
            }else if(!myNumbers.numberStatus[2]){
              myNumbers.buttonValues['numberimage2'] = imagenumber;
              myNumbers.numberStatus[2] =true;
            }else if(!myNumbers.numberStatus[3]){
              myNumbers.buttonValues['numberimage3'] = imagenumber;
              myNumbers.numberStatus[3] =true;
            }else if(!myNumbers.numberStatus[4]){
              myNumbers.buttonValues['numberimage4'] = imagenumber;
              myNumbers.numberStatus[4] =true;
            }
          });
          final assetsAudioPlayer = AssetsAudioPlayer();
          assetsAudioPlayer.open(
            Audio("assets/audios/click.wav"),
          );
        },
        padding: EdgeInsets.all(0),
        child: Image.asset('images/$imagenumber'),
      ),
    );
  }

  FlatButton showDeleteNumbers(statusNumber,number){
    return FlatButton(
      onPressed: (){
        setState(() {
          myNumbers.numberStatus[statusNumber] =false;
          myNumbers.buttonValues[number] = 'nonumber.png';
        });
      },
      child: Image.asset('images/'+myNumbers.buttonValues['$number']),
    );
  }




  @override
  Widget build(BuildContext context) {
    userdoc = _firestore.collection(collectionPath).doc(docPath);
    if(_error) {
      return Text('error-game', textDirection: TextDirection.ltr);
    }

    // Show a loader until FlutterFire is initialized
    if (!_initialized) {
      return Text('Loading', textDirection: TextDirection.ltr);
    }
    return StreamBuilder<DocumentSnapshot>(
      stream: userdoc.snapshots(),
      builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
        if (snapshot.hasError) {
          return Text('Something went wrong');
        }

        if (snapshot.connectionState == ConnectionState.waiting) {
          return Text("Loading");
        }
        if(snapshot.hasData){
          Map<String, dynamic> userDocument  = snapshot.data.data();
          print(collectionPath);
          print(docPath);
          print(snapshot.data);
          print(userDocument);
          return MaterialApp(
            home:Scaffold(
              appBar: AppBar(
                backgroundColor: Colors.amberAccent,
                title: Text('Sayı Avı Oyun Ekranı'),
              ),
              body:Column(
                children: <Widget>[
                  Expanded(
                    flex: 80,
                    child: Row(
                      children: <Widget>[
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getUserNumbers(),
                          ),
                        ),
                        Expanded(
                          flex: 50,
                          child: Column(
                            children: myNumbers.getOpponentNumbers(),
                          ),
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    flex:10,
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: <Widget>[
                        showDeleteNumbers(1,'numberimage1'),
                        showDeleteNumbers(2,'numberimage2'),
                        showDeleteNumbers(3,'numberimage3'),
                        showDeleteNumbers(4,'numberimage4'),
                      ],
                    ),
                  ),
                  Expanded(
                    flex: 10,
                    child: Row(
                      children: <Widget>[
                        attachNumber('one.png'),
                        attachNumber('two.png'),
                        attachNumber('three.png'),
                        attachNumber('four.png'),
                        attachNumber('five.png'),
                        attachNumber('six.png'),
                        attachNumber('seven.png'),
                        attachNumber('eight.png'),
                        attachNumber('nine.png'),
                        attachNumber('zero.png'),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          );
        }
      },
    );
  }
}