How to use SizeChangedLayoutNotifier?

2020-07-24 04:18发布

问题:

I got a Wrap inside my flexibleSpace in my SliverAppBar. Now when the size of my Wrap changes (dynamically) I need to get a notification, so I can change the height of my flexibleSpace in my SliverAppBar accordingly.

I read the docs to the SizeChangedLayoutNotifier but I don't really understand how to use it. I wrapped my Wrap as a child in a SizeChangedLayoutNotifier but for me it is very unclear how to catch the notification with the NotificationListener<SizeChangedLayoutNotification>. I couldn't find any code example.

I would really appreciate your help :) Thanks!

回答1:

I finally figured it out and will post the solution here for others, having the same problem.

I put my Wrap inside like this:

new NotificationListener<SizeChangedLayoutNotification>(
   onNotification: gotNotification,
   child: SizeChangedLayoutNotifier(
       key: _filterBarChangeKey,
       child: Wrap( // my WRAP stuff)
   )
);

and having my callback like this:

bool gotNotification(SizeChangedLayoutNotification notification) {
    // change height here
    _filterBarChangeKey = GlobalKey();
}

I also found another solution from here not using SizeChangedLayoutNotification at all to solve my problem. For me this was even better. I just wrapped my Widget inside an MeaserSize widget which provides an onSizeChanged callback.

typedef void OnWidgetSizeChange(Size size);

class MeasureSize extends StatefulWidget {
  final Widget child;
  final OnWidgetSizeChange onChange;

  const MeasureSize({
    Key key,
    @required this.onChange,
    @required this.child,
  }) : super(key: key);

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

class _MeasureSizeState extends State<MeasureSize> {
  var widgetKey = GlobalKey();

  @override
  Widget build(BuildContext context) {

    WidgetsBinding.instance
        .addPostFrameCallback((_) =>  widget.onChange(widgetKey.currentContext.size));

    return Container(
      key: widgetKey,
      child: widget.child,
    );
  }
}