flutter_overlay_window
flutter_overlay_window copied to clipboard
Values in resizeOverlay not coherent with values in showOverlay
I'm showing an overlay with parameters width: 500, height: 200
without any issue, then I try to double the height doing FlutterOverlayWindow.resizeOverlay(500, 400)
and the window grows far too much, both in width and height. I've been trying with other values, trying to guess some correlation but to no avail, it seems like the two methods accept different units.
Looking source code of OverlayService
I see you are applying dpToPx
to parameters of resizeOverlay
buy not applying it to parameters of showOverlay
. I hope that will be a hint.
The initial width/height does not take in to account the display metrics whilst resizeOverlay does. A workaround is to apply the display metrics yourself when setting the initial width/height by multiplying your desired size by MediaQuery.devicePixelRatioOf(context)
. The result is not exactly identical as there seems to be a rounding difference but it should be within 1px.
EDIT: The rounding difference is avoidable. The resizeOverlay
method applies the display metrics and then truncates (drops the decimal) the resulting width/height since it needs to be specified as an int. My setting of the initial width/height was rounding up to make sure I have at least as much space as I ask for. Two options to get a more consistent size:
- When applying the device pixel ratio to the original width/height, round down. This can result in a slightly lower size than desired.
- When calling resizeOverlay we can round up the width/height so that when it is multiplied by the device pixel ratio and then truncated it will be at least as large as our desired width/height. Unfortunately since the arguments to resizeOverlay are
int
s we cannot totally avoid unnecessary rounding up (without modifying the package). Here is an example method:
static Future<bool?> resizeOverlay(BuildContext context, Size size) {
final devicePixelRatio = MediaQuery.devicePixelRatioOf(context);
final adjustedWidth =
(((size.width * devicePixelRatio).ceilToDouble()) / devicePixelRatio)
.ceil();
final adjustedHeight =
(((size.height * devicePixelRatio).ceilToDouble()) / devicePixelRatio)
.ceil();
return FlutterOverlayWindow.resizeOverlay(adjustedWidth, adjustedHeight);
}
Why was resizeOverlay
written that way, seems unnecessary to me. Can someone explain pls?
The initial width/height does not take in to account the display metrics whilst resizeOverlay does. A workaround is to apply the display metrics yourself when setting the initial width/height by multiplying your desired size by
MediaQuery.devicePixelRatioOf(context)
. The result is not exactly identical as there seems to be a rounding difference but it should be within 1px.EDIT: The rounding difference is avoidable. The
resizeOverlay
method applies the display metrics and then truncates (drops the decimal) the resulting width/height since it needs to be specified as an int. My setting of the initial width/height was rounding up to make sure I have at least as much space as I ask for. Two options to get a more consistent size:
- When applying the device pixel ratio to the original width/height, round down. This can result in a slightly lower size than desired.
- When calling resizeOverlay we can round up the width/height so that when it is multiplied by the device pixel ratio and then truncated it will be at least as large as our desired width/height. Unfortunately since the arguments to resizeOverlay are
int
s we cannot totally avoid unnecessary rounding up (without modifying the package). Here is an example method:static Future<bool?> resizeOverlay(BuildContext context, Size size) { final devicePixelRatio = MediaQuery.devicePixelRatioOf(context); final adjustedWidth = (((size.width * devicePixelRatio).ceilToDouble()) / devicePixelRatio) .ceil(); final adjustedHeight = (((size.height * devicePixelRatio).ceilToDouble()) / devicePixelRatio) .ceil(); return FlutterOverlayWindow.resizeOverlay(adjustedWidth, adjustedHeight); }
I have the similar issue with this. " await FlutterOverlayWindow.showOverlay( enableDrag: true, overlayTitle: "来电显示", overlayContent: "name:${callerIdData.phoneNumber},region:${callerIdData.countryName},carrier:${callerIdData.carrier}", alignment: OverlayAlignment.center, flag: OverlayFlag.defaultFlag, visibility: overlay.NotificationVisibility.visibilityPublic, positionGravity: PositionGravity.auto, height: (styleProvider.windowHeight * (pixelRatio ?? 3.0)) .toInt(), // 使用 styleProvider.windowHeight width: (styleProvider.windowWidth * (pixelRatio ?? 3.0)).toInt()," i have to use "PixelRatio = MediaQuery.of(context).devicePixelRatio" other wise It will be 1/3 than its real size, I don't know what is the issue with this
The initial width/height does not take in to account the display metrics whilst resizeOverlay does. A workaround is to apply the display metrics yourself when setting the initial width/height by multiplying your desired size by
MediaQuery.devicePixelRatioOf(context)
. The result is not exactly identical as there seems to be a rounding difference but it should be within 1px. EDIT: The rounding difference is avoidable. TheresizeOverlay
method applies the display metrics and then truncates (drops the decimal) the resulting width/height since it needs to be specified as an int. My setting of the initial width/height was rounding up to make sure I have at least as much space as I ask for. Two options to get a more consistent size:
- When applying the device pixel ratio to the original width/height, round down. This can result in a slightly lower size than desired.
- When calling resizeOverlay we can round up the width/height so that when it is multiplied by the device pixel ratio and then truncated it will be at least as large as our desired width/height. Unfortunately since the arguments to resizeOverlay are
int
s we cannot totally avoid unnecessary rounding up (without modifying the package). Here is an example method:static Future<bool?> resizeOverlay(BuildContext context, Size size) { final devicePixelRatio = MediaQuery.devicePixelRatioOf(context); final adjustedWidth = (((size.width * devicePixelRatio).ceilToDouble()) / devicePixelRatio) .ceil(); final adjustedHeight = (((size.height * devicePixelRatio).ceilToDouble()) / devicePixelRatio) .ceil(); return FlutterOverlayWindow.resizeOverlay(adjustedWidth, adjustedHeight); }
I have the similar issue with this. " await FlutterOverlayWindow.showOverlay( enableDrag: true, overlayTitle: "来电显示", overlayContent: "name:${callerIdData.phoneNumber},region:${callerIdData.countryName},carrier:${callerIdData.carrier}", alignment: OverlayAlignment.center, flag: OverlayFlag.defaultFlag, visibility: overlay.NotificationVisibility.visibilityPublic, positionGravity: PositionGravity.auto, height: (styleProvider.windowHeight * (pixelRatio ?? 3.0)) .toInt(), // 使用 styleProvider.windowHeight width: (styleProvider.windowWidth * (pixelRatio ?? 3.0)).toInt()," i have to use "PixelRatio = MediaQuery.of(context).devicePixelRatio" other wise It will be 1/3 than its real size, I don't know what is the issue with this
Unfortunately, I had to go into the code and change the resize method myself