Skip to content

Consider following screen/body approach #77

@nivisi

Description

@nivisi

The problem

When creating a screen, sometimes we need to add a lot of top-level configuration widgets:

  // screen.dart
  @override
  Widget build(BuildContext context) {
    // 1
    return FocusScopeDismissible(
      // 2
      child: BlocProvider<Bloc>(
        create: (context) => injector(),
        // Aand the actual UI comes at this point...
        // 3
        child: Scaffold(
          // Aand the core part of it is here
          body: Column(
            children: const [],
          ),
        ),
      ),
    );
  }

At least 3 top-level things just to make the screen work normally. And it can be more.

The solution

The body of the screen could be moved to a separate widget:

  // screen.dart
  @override
  Widget build(BuildContext context) {
    return FocusScopeDismissible(
      child: BlocProvider<Bloc>(
        create: (context) => injector(),
        child: Scaffold(
          body: const ScreenBody(),
        ),
      ),
    );
  }

  ...

class ScreenBody extends StatelessWidget {
  const ScreenBody({super.key});

  @override
  Widget build(BuildContext context) {
    // The bloc's data could still be accessible via selectors and bloc builders
    final stateData = context.select((Bloc bloc) => bloc.state.data);

    return const Text("I'm the actual UI of the screen!");
  }
}

Pros

  • Makes you to follow smaller widgets approach;
  • Reduces the waterfall in the body of a screen.

Cons

  • So far I don't see it. We followed this approach on two projects and it was quite good.

Additional instruments that may help us

We can write a simple script that will generate the files on command from our IDE. I have already written a very similar script for a VSCode extension for my package, it is here. It can be a create_feature, not a module.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions