flutter 值为false,但仍给出错误空值检查运算符

mo49yndu  于 2023-02-13  发布在  Flutter
关注(0)|答案(3)|浏览(133)

当看到代码和错误时,您会更好地理解。
我有一个StatelessWidget,它的名字是这样的:

class StateWidget extends StatelessWidget {
  const StateWidget({
    super.key,
    required this.readyWidget,
    this.error = false,
    this.errorWidget,
    this.loading = false,
    this.loadingWidget,
  });

  final Widget readyWidget;
  final bool error;
  final Widget? errorWidget;
  final bool loading;
  final Widget? loadingWidget;

  @override
  Widget build(BuildContext context) {
    if (loading) {
      return loadingWidget ?? LoadingCircularProgressIndicatorWidget();
    }

    if (error) {
      return errorWidget ?? ErrorIconWidget();
    }

    if (!loading && !error) return readyWidget;

    return Container();
  }
}

我有一个名为StateWidgetExampleView的状态控件,如下所示:

class StateWidgetExampleView extends StatefulWidget {
  const StateWidgetExampleView({super.key});

  @override
  State<StateWidgetExampleView> createState() => _StateWidgetExampleViewState();
}

class _StateWidgetExampleViewState extends State<StateWidgetExampleView> {
  bool loading = true;
  String? data;

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

    Future.delayed(Duration(milliseconds: 1000)).then((value) {
      data = "Gelen Veri!";
      setState(() {
        loading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("StateWidgetExampleView"),
      ),
      body: StateWidget(
        loading: loading,
        error: data == null,
        readyWidget: Text(data!),
      ),
    );
  }
}

我在initState函数中得到了一个1秒内的样本数据。你猜"loadingWidget出现是因为加载是真的"。这个想法是正确的,但它抛出了类似Null check operator used on a null value的错误。我认为这呈现了所有的小部件,然后检查条件。让我们看看错误,等待1秒,然后我们的状态小部件准备就绪。我想要一个结构,我可以控制错误,正在加载并准备好小部件。但是它会抛出这样的错误。我怎么才能构建我想要的结构呢?
错误:

正在加载数据:

数据加载:

hs1ihplo

hs1ihplo1#

StateWidget小部件正在从第一帧创建。即使您已经等待了一些帧来处理null。但是
这个

body: StateWidget(
  loading: loading,
  error: data == null,
  readyWidget: Text(data!),/// here means create with current data
),

因此,Text小部件不接受null,并且在使用null-assert时,它会抛出错误。
您在UI上隐藏了错误,而不是在编译器上,因为Text()小工具是从第一帧创建的。
您可以提供默认值,如readyWidget: Text(data??"")

xxe27gdn

xxe27gdn2#

您可以通过使用FutureBuilder小部件来实现所需的功能。

class StateWidgetExampleView extends StatefulWidget {
  const StateWidgetExampleView({super.key});

  @override
  State<StateWidgetExampleView> createState() => _StateWidgetExampleViewState();
}

class _StateWidgetExampleViewState extends State<StateWidgetExampleView> {
  late final Future<String> _data;

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

    _data = Future.delayed(const Duration(milliseconds: 1000)).then((value) {
      return "Gelen Veri!";
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("StateWidgetExampleView"),
      ),
      body: FutureBuilder(
        future: _data,
        builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
          if (snapshot.hasData) {
            return Text(snapshot.data!);
          } else if (snapshot.hasError) {
            return Text('Error: ${snapshot.error}');
          }

          return const Center(child: CircularProgressIndicator());
        },
      ),
    );
  }
}
tyu7yeag

tyu7yeag3#

我把它“readyWidget”改成了“readyBuilder”。所以,我做了一个函数返回小部件。现在没有错误了,这就是我想要的!^^
状态控件示例视图:

class StateWidgetExampleView extends StatefulWidget {
  const StateWidgetExampleView({super.key});

  @override
  State<StateWidgetExampleView> createState() => _StateWidgetExampleViewState();
}

class _StateWidgetExampleViewState extends State<StateWidgetExampleView> {
  bool loading = true;
  String? data;

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

    Future.delayed(Duration(milliseconds: 1000)).then((value) {
      data = "Gelen Veri!";
      setState(() {
        loading = false;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("StateWidgetExampleView"),
      ),
      body: StateWidget(
        loading: loading,
        error: data == null,
        readyBuilder: () => Text(data!),
      ),
    );
  }
}

状态控件:

class StateWidget extends StatelessWidget {
  const StateWidget({
    super.key,
    required this.readyBuilder,
    this.error = false,
    this.errorWidget,
    this.loading = false,
    this.loadingWidget,
  });

  final Widget Function() readyBuilder;
  final bool error;
  final Widget? errorWidget;
  final bool loading;
  final Widget? loadingWidget;

  @override
  Widget build(BuildContext context) {
    return Builder(
      builder: (context) {
        if (loading) {
          return loadingWidget ?? LoadingCircularProgressIndicatorWidget();
        }

        if (error) {
          return errorWidget ?? ErrorIconWidget();
        }

        return readyBuilder();
      },
    );
  }
}

相关问题