Skip to content

Commit baece94

Browse files
committed
ResponsiveScaledBox MediaQueryData Creation
- Auto calculate correct MediaQueryData when used as root widget scaling.
1 parent 09f3de4 commit baece94

1 file changed

Lines changed: 116 additions & 21 deletions

File tree

lib/responsive_scaled_box.dart

Lines changed: 116 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,131 @@
1+
import 'dart:math';
2+
13
import 'package:flutter/material.dart';
24

35
class ResponsiveScaledBox extends StatelessWidget {
46
final double width;
57
final Widget child;
8+
final bool autoCalculateMediaQueryData;
69

710
const ResponsiveScaledBox(
8-
{Key? key, required this.width, required this.child})
11+
{Key? key,
12+
required this.width,
13+
required this.child,
14+
this.autoCalculateMediaQueryData = true})
915
: super(key: key);
1016

1117
@override
1218
Widget build(BuildContext context) {
13-
MediaQueryData mediaQueryData = MediaQuery.of(context);
14-
15-
return MediaQuery(
16-
data: mediaQueryData,
17-
child: LayoutBuilder(
18-
builder: (context, constraints) {
19-
double aspectRatio = constraints.maxWidth / constraints.maxHeight;
20-
double scaledHeight = width / aspectRatio;
21-
22-
return FittedBox(
23-
fit: BoxFit.fitWidth,
24-
alignment: Alignment.topCenter,
25-
child: Container(
26-
width: width,
27-
height: scaledHeight,
28-
alignment: Alignment.center,
29-
child: child,
30-
),
19+
return LayoutBuilder(
20+
builder: (context, constraints) {
21+
MediaQueryData mediaQueryData = MediaQuery.of(context);
22+
23+
double aspectRatio = constraints.maxWidth / constraints.maxHeight;
24+
double scaledWidth = width;
25+
double scaledHeight = width / aspectRatio;
26+
27+
bool overrideMediaQueryData = autoCalculateMediaQueryData &&
28+
(mediaQueryData.size ==
29+
Size(constraints.maxWidth, constraints.maxHeight));
30+
31+
EdgeInsets scaledViewInsets = getScaledViewInsets(
32+
mediaQueryData: mediaQueryData,
33+
screenSize: mediaQueryData.size,
34+
scaledSize: Size(scaledWidth, scaledHeight));
35+
EdgeInsets scaledViewPadding = getScaledViewPadding(
36+
mediaQueryData: mediaQueryData,
37+
screenSize: mediaQueryData.size,
38+
scaledSize: Size(scaledWidth, scaledHeight));
39+
EdgeInsets scaledPadding = getScaledPadding(
40+
padding: scaledViewPadding, insets: scaledViewInsets);
41+
42+
Widget childHolder = FittedBox(
43+
fit: BoxFit.fitWidth,
44+
alignment: Alignment.topCenter,
45+
child: Container(
46+
width: width,
47+
height: scaledHeight,
48+
alignment: Alignment.center,
49+
child: child,
50+
),
51+
);
52+
53+
if (overrideMediaQueryData) {
54+
return MediaQuery(
55+
data: mediaQueryData.copyWith(
56+
size: Size(scaledWidth, scaledHeight),
57+
viewInsets: scaledViewInsets,
58+
viewPadding: scaledViewPadding,
59+
padding: scaledPadding),
60+
child: childHolder,
3161
);
32-
},
33-
),
62+
}
63+
64+
return childHolder;
65+
},
3466
);
3567
}
68+
69+
EdgeInsets getScaledViewInsets(
70+
{required MediaQueryData mediaQueryData,
71+
required Size screenSize,
72+
required Size scaledSize}) {
73+
double leftInsetFactor = mediaQueryData.viewInsets.left / screenSize.width;
74+
double topInsetFactor = mediaQueryData.viewInsets.top / screenSize.height;
75+
double rightInsetFactor =
76+
mediaQueryData.viewInsets.right / screenSize.width;
77+
double bottomInsetFactor =
78+
mediaQueryData.viewInsets.bottom / screenSize.height;
79+
80+
double scaledLeftInset = leftInsetFactor * scaledSize.width;
81+
double scaledTopInset = topInsetFactor * scaledSize.height;
82+
double scaledRightInset = rightInsetFactor * scaledSize.width;
83+
double scaledBottomInset = bottomInsetFactor * scaledSize.height;
84+
85+
return EdgeInsets.fromLTRB(
86+
scaledLeftInset, scaledTopInset, scaledRightInset, scaledBottomInset);
87+
}
88+
89+
EdgeInsets getScaledViewPadding(
90+
{required MediaQueryData mediaQueryData,
91+
required Size screenSize,
92+
required Size scaledSize}) {
93+
double scaledLeftPadding;
94+
double scaledTopPadding;
95+
double scaledRightPadding;
96+
double scaledBottomPadding;
97+
98+
double leftPaddingFactor =
99+
mediaQueryData.viewPadding.left / screenSize.width;
100+
double topPaddingFactor =
101+
mediaQueryData.viewPadding.top / screenSize.height;
102+
double rightPaddingFactor =
103+
mediaQueryData.viewPadding.right / screenSize.width;
104+
double bottomPaddingFactor =
105+
mediaQueryData.viewPadding.bottom / screenSize.height;
106+
107+
scaledLeftPadding = leftPaddingFactor * scaledSize.width;
108+
scaledTopPadding = topPaddingFactor * scaledSize.height;
109+
scaledRightPadding = rightPaddingFactor * scaledSize.width;
110+
scaledBottomPadding = bottomPaddingFactor * scaledSize.height;
111+
112+
return EdgeInsets.fromLTRB(scaledLeftPadding, scaledTopPadding,
113+
scaledRightPadding, scaledBottomPadding);
114+
}
115+
116+
EdgeInsets getScaledPadding(
117+
{required EdgeInsets padding, required EdgeInsets insets}) {
118+
double scaledLeftPadding;
119+
double scaledTopPadding;
120+
double scaledRightPadding;
121+
double scaledBottomPadding;
122+
123+
scaledLeftPadding = max(0.0, padding.left - insets.left);
124+
scaledTopPadding = max(0.0, padding.top - insets.top);
125+
scaledRightPadding = max(0.0, padding.right - insets.right);
126+
scaledBottomPadding = max(0.0, padding.bottom - insets.bottom);
127+
128+
return EdgeInsets.fromLTRB(scaledLeftPadding, scaledTopPadding,
129+
scaledRightPadding, scaledBottomPadding);
130+
}
36131
}

0 commit comments

Comments
 (0)