refresh method

Future<void> refresh({
  1. Duration? delay,
})

Changes status bar color based on the current background

Important

This operation is computationally expensive to calculate, so therefore must be used with caution.

Error handling

Throws an StatusbarzException if no StatusbarzCapturer found from widget tree.

Statusbarz.instance.observer shall be placed inside MaterialApp in order to change status bar color automatically when new page is pushed/popped:

void main() {
  runApp(
    StatusbarzCapturer(
      child: MaterialApp(
        navigatorObservers: [Statusbarz.instance.observer],
        home: Container(),
      ),
    ),
  );
}

See also:

  • StatusbarzCapturer, the widget used to find the currently rendered object
  • StatusbarzObserver, the observer used to listen to route changes

Implementation

Future<void> refresh({
  Duration? delay,
}) async {
  return Future.delayed(
    delay ?? _defaultDelay,
    () async {
      final context = _key.currentContext;

      if (context == null) {
        throw StatusbarzException(
          'No StatusbarzObserver found from widget tree. StatusbarzObserver shall be added above MaterialApp in your widget tree.',
        );
      }
      final view = View.of(context);

      /// Finds currently rendered UI
      final boundary = context.findRenderObject() as RenderRepaintBoundary?;

      /// Converts rendered UI to png
      final capturedImage = await boundary!.toImage();
      final byteData =
          await capturedImage.toByteData(format: ImageByteFormat.png);
      final bytes = byteData!.buffer.asUint8List();

      final bitmap = img.decodeImage(bytes);

      var luminance = 0.0;
      var pixels = 0;
      //final window = WidgetsBinding.instance.window;

      final mediaQuery = MediaQueryData.fromView(view);
      final statusHeight = mediaQuery.padding.top.clamp(20.0, 150.0);

      /// Calculates the average color for the status bar
      for (var yCoord = 0; yCoord < statusHeight.toInt(); yCoord++) {
        for (var xCoord = 0; xCoord < bitmap!.width; xCoord++) {
          final pixel = bitmap.getPixel(xCoord, yCoord);
          luminance += pixel.luminance;
          pixels++;
        }
      }

      final avgLuminance = luminance / pixels;

      /// Updates status bar color
      if (avgLuminance > 0.5) {
        setDarkStatusBar();
      } else {
        setLightStatusBar();
      }
    },
  );
}