Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Widget fails to render when a Stack widget is used #93

Open
loongyeat opened this issue May 7, 2022 · 1 comment
Open

Widget fails to render when a Stack widget is used #93

loongyeat opened this issue May 7, 2022 · 1 comment

Comments

@loongyeat
Copy link

As title implies. Console shows flutter: Null check operator used on a null value. To re-create:

class SomeWidget extends StatelessWidget {
  const SomeWidget({Key? key}) : super(key: key);

  static final _key = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          final exporter = _key.currentWidget as DynamicWidgetJsonExportor?;
          final exportedJsonString = exporter?.exportJsonString();

          if (exportedJsonString == null) {
            return;
          }

          Navigator.of(context).push<void>(
            MaterialPageRoute(
              builder: (context) => const RendererWidget(exportedJsonString),
            ),
          );
        },
        child: const Icon(Icons.copy),
      ),
      body: DynamicWidgetJsonExportor(
        key: _key,
        child: _buildSimpleWidget(),
      ),
    );
  }

  Widget _buildSimpleWidget() {
    return Stack(
      children: [
        Icon(Icons.star),
        Icon(Icons.abc),
      ],
    );
  }
}

class RendererWidget extends StatelessWidget {
  const RendererWidget(this.json, {Key? key}) : super(key: key);

  final String json;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(),
      body: SafeArea(
        child: FutureBuilder<Widget?>(
          future: _buildWidget(context),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              print(snapshot.error);
            }

            if (!snapshot.hasData) {
              return Container();
            }

            return SizedBox.expand(
              child: snapshot.data,
            );
          },
        ),
      ),
    );
  }

  Future<Widget?> _buildWidget(BuildContext context) async {
    return Future.delayed(const Duration(seconds: 1), () {
      return DynamicWidgetBuilder.build(
        json,
        context,
        DefaultClickListener(),
      );
    });
  }
}

class DefaultClickListener implements ClickListener {
  @override
  void onClicked(String? event) {
    print(event);
  }
}
@dengyin2000
Copy link
Owner

As title implies. Console shows flutter: Null check operator used on a null value. To re-create:

class SomeWidget extends StatelessWidget {
  const SomeWidget({Key? key}) : super(key: key);

  static final _key = GlobalKey();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          final exporter = _key.currentWidget as DynamicWidgetJsonExportor?;
          final exportedJsonString = exporter?.exportJsonString();

          if (exportedJsonString == null) {
            return;
          }

          Navigator.of(context).push<void>(
            MaterialPageRoute(
              builder: (context) => const RendererWidget(exportedJsonString),
            ),
          );
        },
        child: const Icon(Icons.copy),
      ),
      body: DynamicWidgetJsonExportor(
        key: _key,
        child: _buildSimpleWidget(),
      ),
    );
  }

  Widget _buildSimpleWidget() {
    return Stack(
      children: [
        Icon(Icons.star),
        Icon(Icons.abc),
      ],
    );
  }
}

class RendererWidget extends StatelessWidget {
  const RendererWidget(this.json, {Key? key}) : super(key: key);

  final String json;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(),
      body: SafeArea(
        child: FutureBuilder<Widget?>(
          future: _buildWidget(context),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              print(snapshot.error);
            }

            if (!snapshot.hasData) {
              return Container();
            }

            return SizedBox.expand(
              child: snapshot.data,
            );
          },
        ),
      ),
    );
  }

  Future<Widget?> _buildWidget(BuildContext context) async {
    return Future.delayed(const Duration(seconds: 1), () {
      return DynamicWidgetBuilder.build(
        json,
        context,
        DefaultClickListener(),
      );
    });
  }
}

class DefaultClickListener implements ClickListener {
  @override
  void onClicked(String? event) {
    print(event);
  }
}

I try your code, it seems it's ok. the "exportedJsonString" is

exportedJsonString: {"type":"Stack","alignment":"topStart","textDirection":"ltr","fit":"loose","clipBehavior":"hardEdge","children":[{"type":"Icon","data":"star","size":null,"color":null,"semanticLabel":null,"textDirection":null},{"type":"Icon","data":"ac_unit","size":null,"color":null,"semanticLabel":null,"textDirection":null}]}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants