我正在努力打造我的第一个Flutter 翼项目.这是从下拉列表中 Select 用户的初始视图. 其 idea 是,当用户被选中时,文本应该显示该用户的一些信息,并根据信息显示登录按钮或注销按钮

但我在启动时收到一个意外的空值

有谁能帮帮我吗?

谢谢!

import 'package:flutter/material.dart';
import 'package:geolocator/geolocator.dart';

class UserScreen extends StatefulWidget {
  @override
  _UserState createState() => _UserState();
}

class _UserState extends State<UserScreen> {
  String? dropdownvalue;
  Position? position;
  String? mvt;
  List<Row> _widgetList = [];

  @override
  void initState() {
    super.initState();
    getAllUsers().then((value) => {dropdownvalue = value[0]});
    getCurrentPosition().then((value) => position = value);
    mvt = "";
    _widgetList
        .add(UserSelect(mvt!, dropdownvalue!, position!, _widgetList) as Row);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Center(
            child: Padding(
                padding: EdgeInsets.fromLTRB(0, 5, 0, 0),
                child: Text(
                  'MY APP',
                  style: TextStyle(
                    color: Colors.orange,
                    fontSize: 16,
                  ),
                  textAlign: TextAlign.center,
                ))),
        backgroundColor: Color.fromARGB(255, 11, 11, 11),
        automaticallyImplyLeading: false,
        actions: [
          Row(
            mainAxisAlignment: MainAxisAlignment.end,
            children: [
              Padding(padding: EdgeInsets.fromLTRB(0, 35, 50, 0)),
              IconButton(
                  onPressed: () {
                    Navigator.pushNamed(context, '/admin');
                  },
                  icon: Icon(Icons.admin_panel_settings,
                      color: Colors.orange, size: 25))
            ],
          ),
        ],
      ),
      backgroundColor: Color.fromARGB(255, 11, 11, 11),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
                decoration:
                    BoxDecoration(color: Color.fromARGB(255, 11, 11, 11)),
                child: Column(children: [
                  Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      mainAxisSize: MainAxisSize.min,
                      children: [
                        SizedBox(
                          width: 200,
                          height: 30,
                          child: Text(
                            "SELECT YOUR USERNAME",
                            style: TextStyle(
                              color: Colors.orange,
                            ),
                          ),
                        )
                      ]),
                  ListView(
                    children: _widgetList,
                  ),
                ]))
          ],
        ),
      ),
    );
  }
}

class UserSelect extends StatefulWidget {
  UserSelect(String move, String s, Position position, List<Row> widgetList);

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

class _UserSelect extends State<UserSelect> {
  late String move;
  late String usu;
  late Position pos;
  late List<Row> _widgetList;

  @override
  void initState() {
    super.initState();
    getAllUsers().then((value) => {usu = value[0]});
    getCurrentPosition().then((value) => pos = value);
    move = "";
    _widgetList = this._widgetList;
  }

  //UserSelect(this.move, this.usu, this.pos, this._widgetList);

  @override
  Widget build(BuildContext context) {
    return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
              width: 300,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.orange,
                ),
                child: Column(children: [
                  FutureBuilder<List<String>>(
                    future: getAllUsers(),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        var data = snapshot.data!;
                        return Container(
                            child: DropdownButtonHideUnderline(
                                child: ButtonTheme(
                                    alignedDropdown: true,
                                    child: DropdownButton(
                                      padding:
                                          EdgeInsets.fromLTRB(40, 0, 40, 0),
                                      isExpanded: true,
                                      // Initial Value
                                      value: usu,
                                      // Down Arrow Icon
                                      icon:
                                          const Icon(Icons.keyboard_arrow_down),
                                      // Array list of items
                                      items: data.map((String items) {
                                        return DropdownMenuItem(
                                            value: items,
                                            child: Text(items),
                                            alignment: Alignment.center);
                                      }).toList(),
                                      // After selecting the desired option,it will
                                      // change button value to selected value
                                      onChanged: (String? newValue) {
                                        setState(() {
                                          usu = newValue!;
                                          move = getNextMovement(usu) as String;
                                          _widgetList.add(
                                              UserNextMove(move, usu, pos)
                                                  as Row);
                                        });
                                      },
                                    ))));
                      } else {
                        return const CircularProgressIndicator();
                      }
                    },
                  ),
                ]),
              )),
        ]);
  }
}

class UserNextMove extends State<UserSelect> {
  final String move;
  final String usu;
  final Position pos;

  UserNextMove(this.move, this.usu, this.pos);

  @override
  Widget build(BuildContext context) {
    return Row(children: [
      Row(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.min,
          children: [
            SizedBox(
                width: 300,
                child: Container(
                    decoration: BoxDecoration(
                      color: Color.fromARGB(255, 11, 11, 11),
                    ),
                    child: Text("YOUR NEXT MOVEMENT SHOULD BE $move",
                        style: TextStyle(color: Colors.orange))))
          ]),
      Row(children: [
        move == "ENTRADA"
            ? ElevatedButton.icon(
                label: Text("LOG IN",
                    style: TextStyle(
                      color: Colors.white,
                    )),
                icon: Icon(Icons.login),
                style: ButtonStyle(
                    backgroundColor:
                        MaterialStateProperty.all(Colors.greenAccent)),
                onPressed: () {
                  if (usu != "") {
                    Navigator.pushNamed(context, '/cam',
                        arguments: ScreenArguments(usu, pos, move));
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                      behavior: SnackBarBehavior.floating,
                      width: 200,
                      backgroundColor: Colors.red,
                      content: new Text(
                        "SELECT A VALID USER",
                        textAlign: TextAlign.center,
                      ),
                      duration: new Duration(seconds: 10),
                    ));
                  }
                },
              )
            : ElevatedButton.icon(
                label: Text("LOG OUT",
                    style: TextStyle(
                      color: Colors.white,
                    )),
                icon: Icon(Icons.login),
                style: ButtonStyle(
                    backgroundColor:
                        MaterialStateProperty.all(Colors.redAccent)),
                onPressed: () {
                  if (usu != "") {
                    Navigator.pushNamed(context, '/cam',
                        arguments: ScreenArguments(usu, pos, move));
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(SnackBar(
                      behavior: SnackBarBehavior.floating,
                      width: 200,
                      backgroundColor: Colors.red,
                      content: new Text(
                        "SELECT A VALID USER",
                        textAlign: TextAlign.center,
                      ),
                      duration: new Duration(seconds: 10),
                    ));
                  }
                },
              )
      ])
    ]);
  }
}

Getalluser()是一个调用API并返回用户名列表(可以使用)的函数. GetCurrentPosition()是一个通用的地理定位器函数(可以工作) Getnextmoval()是一个函数,它根据用户名调用一个API并返回他应该执行哪个移动(这是可行的)

如果 Select 了用户,这if (usu != "") {Navigator.pushNamed(context, '/cam',arguments: ScreenArguments(usu, pos, move));只会将用户重定向到摄像头(也可以)

提前谢谢您!

推荐答案

GetAllUser()和getCurrentPosition()都返回Future值,因此它们可能不会在小部件生成时完成.
usu变量不应为‘Late’并在initState()中初始化,它应该是可以为空的字符串,并从FutureBuilder的Snapshot t.data赋值.
您需要为pos变量另一个嵌套的FutureBuilder,并从Snapshot t.data赋值(与usu变量相同).
希望这会有所帮助.

*回答以下 comments :
我没有你所有的代码来判断语法,所以我只是更新了你的代码,没有语法判断,只是为了让你知道这个 idea .

class _UserSelect extends State<UserSelect> {
  late String move;
  // late String usu;
  String? usu;
  // late Position pos;
  Position? pos;
  late List<Row> _widgetList;

  @override
  void initState() {
    super.initState();
    // not call here as it doesn't help
    // getAllUsers().then((value) => {usu = value[0]});
    // getCurrentPosition().then((value) => pos = value);
    move = "";
    _widgetList = this._widgetList;
  }

  //UserSelect(this.move, this.usu, this.pos, this._widgetList);

  @override
  Widget build(BuildContext context) {
    return Row(
        mainAxisAlignment: MainAxisAlignment.center,
        mainAxisSize: MainAxisSize.min,
        children: [
          SizedBox(
              width: 300,
              child: Container(
                decoration: BoxDecoration(
                  color: Colors.orange,
                ),
                child: Column(children: [
                  FutureBuilder<List<String>>(
                    future: getAllUsers(),
                    builder: (context, snapshot) {
                      if (snapshot.hasData) {
                        var data = snapshot.data!;
                        // assign usu here
                        usu = data[0];
                        // retrieve pos here
                        return FutureBuilder<Position>(
                          builder: (context, snapshot) {
                            future: getCurrentPosition(),
                            if (snapshot.hasData) {
                              // Asign pos here
                              var pos = snapshot.data!;
                            return Container(
                                child: DropdownButtonHideUnderline(
                                    child: ButtonTheme(
                                        alignedDropdown: true,
                                        child: DropdownButton(
                                          padding:
                                              EdgeInsets.fromLTRB(40, 0, 40, 0),
                                          isExpanded: true,
                                          // Initial Value
                                          value: usu,
                                          // Down Arrow Icon
                                          icon:
                                              const Icon(Icons.keyboard_arrow_down),
                                          // Array list of items
                                          items: data.map((String items) {
                                            return DropdownMenuItem(
                                                value: items,
                                                child: Text(items),
                                                alignment: Alignment.center);
                                          }).toList(),
                                          // After selecting the desired option,it will
                                          // change button value to selected value
                                          onChanged: (String? newValue) {
                                            setState(() {
                                              usu = newValue!;
                                              move = getNextMovement(usu) as String;
                                              _widgetList.add(
                                                  UserNextMove(move, usu, pos)
                                                      as Row);
                                            });
                                          },
                                        ))));
                            } else {
                              return const CircularProgressIndicator();
                            }
                          }
                        );
                      } else {
                        return const CircularProgressIndicator();
                      }
                    },
                  ),
                ]),
              )),
        ]);
  }
}

希望这能帮上忙.

Flutter相关问答推荐

Flutter在创建时为提供者调用初始化函数

为什么他们实例化类,然后丢弃该实例?

Flutter 应用程序中的Firebase实时数据库中的orderByChild()不适用于我

我怎样才能在Ffltter中显示html布局链接?

如果我使用搜索栏,如何在嵌套滚动视图中停止自动滚动?

Riverpod 2.0-如何使用FutureOr和AutoDisposeSyncNotificationer处理api状态代码?

Flutter Xcode 15 错误(Xcode):DT_TOOLCHAIN_DIR 无法用于判断 LIBRARY_SEARCH_PATHS

尽管我的 url 链接正确,但 ArgumentError(无效参数:URI 文件中未指定主机:///)错误

Flutter记录返回类型问题

在flutter中从图库或相机中 Select 图像的方法

如何使 flutter 2 手指zoom ?

不使用 GlobalKey 仍然收到 GlobalKey 被多次使用的错误

Flutter - 如何将按钮对齐到行的右侧

如何修复 ICU Lexing 错误:Flutter 中的意外字符

如何验证非表单字段?

Flutter 中的 Firebase 后台消息处理程序产生重复的隔离并运行应用程序两次

如何在 ListView.builder 中扩展文本?

我的主屏幕上的 FutureBuilder 不断重新加载(但仅在其他屏幕上时)?

Flutter 评级栏包选中和未选中的容器

Flutter Firebase 可以在真实设备上运行,而不是在 Android 模拟器上运行