Home > Software design >  Substitute a child of a widget by another widget / optionally wrapping a widget
Substitute a child of a widget by another widget / optionally wrapping a widget

Time:09-21

Is it possible to "merge" two widgets together? I want to build an OptionalWrapper component, that wraps a widget by another widget only if a condition is matched.

The usage should look something like this, I provide a child and if the showWrapper condition is true, this child is put as the child of the wrapper widget.

OptionalWrapper(
  showWrapper: !isSmallScreen(context),
  wrapper: Padding(
    padding: const EdgeInsets.only(top: 16.0),
    child: // <-- Here should the child be rendered
  ),
  child: Text("Hello"),
),

of course I could do something like this:

!isSmallScreen(context) ? Padding(
  padding: const EdgeInsets.all(16.0),
  child: Text("Hello"),
) : Text("Hello"),

But here I declare my Text widget twice which I want to avoid.

The implementation would look like this:

import 'package:flutter/material.dart';

class OptionalWrapper extends StatelessWidget {
  final bool showWrapper;
  final Widget wrapper;
  final Widget child;

  const OptionalWrapper({
    Key? key,
    required this.showWrapper,
    required this.wrapper,
    required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (showWrapper) {
      // return the wrapper widget but subject child as child of the wrapper widget
    } else {
      return child;
    }
  }
}

CodePudding user response:

You can create builder method like

import 'package:flutter/material.dart';

class OptionalWrapper extends StatelessWidget {
  final bool showWrapper;
  final Widget Function(Widget) wrapper;
  final Widget child;

  const OptionalWrapper({
    Key? key,
    required this.showWrapper,
    required this.wrapper,
    required this.child,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    if (showWrapper) {
      return wrapper(child);
    } else {
      return child;
    }
  }
}

CodePudding user response:

You can make the padding as EdgeInsects.zero if the condition fails

 Padding(
      padding: !isSmallScreen(context)?const EdgeInsets.all(16.0): EdgeInsects.zero,
      child: Text("Hello"),
  • Related