Skip to content

Commit bedb154

Browse files
committed
Make mandatory (small/normal/large) and improve device detection (watch/phone/tablet/desktop).
1 parent eec596b commit bedb154

File tree

13 files changed

+154
-69
lines changed

13 files changed

+154
-69
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.8.8
2+
3+
- Make `ScreenBreakpoints.normal` mandatory (small/normal/large) and improve device detection (watch/phone/tablet/desktop).
4+
15
## 0.8.7
26

37
- Similar to 0.8.6 with changes to the `README.md`.

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ It aims to provide you with widgets that make it easy to build different UI's al
1313
Add responsive_builder as dependency to your pubspec file.
1414

1515
```
16-
responsive_builder2: ^0.8.7
16+
responsive_builder2: ^0.8.8
1717
```
1818

1919
## Usage
@@ -167,9 +167,9 @@ import 'package:responsive_builder2/responsive_builder2.dart';
167167
//ScreenTypeLayout with custom breakpoints supplied
168168
ScreenTypeLayout(
169169
breakpoints: ScreenBreakpoints(
170-
tablet: 600,
171-
desktop: 950,
172-
watch: 300
170+
small: 300,
171+
normal: 600,
172+
large: 950,
173173
),
174174
mobile: Container(color:Colors.blue),
175175
tablet: Container(color: Colors.yellow),
@@ -187,7 +187,7 @@ If you want to set the breakpoints for the responsive builders once you can call
187187
```dart
188188
void main() {
189189
ResponsiveSizingConfig.instance.setCustomBreakpoints(
190-
ScreenBreakpoints(large: 550, small: 200),
190+
ScreenBreakpoints(small: 200, normal: 550, large: 1000),
191191
);
192192
runApp(MyApp());
193193
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#
2+
# Generated file, do not edit.
3+
#
4+
5+
import lldb
6+
7+
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
8+
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
9+
base = frame.register["x0"].GetValueAsAddress()
10+
page_len = frame.register["x1"].GetValueAsUnsigned()
11+
12+
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
13+
# first page to see if handled it correctly. This makes diagnosing
14+
# misconfiguration (e.g. missing breakpoint) easier.
15+
data = bytearray(page_len)
16+
data[0:8] = b'IHELPED!'
17+
18+
error = lldb.SBError()
19+
frame.GetThread().GetProcess().WriteMemory(base, data, error)
20+
if not error.Success():
21+
print(f'Failed to write into {base}[+{page_len}]', error)
22+
return
23+
24+
def __lldb_init_module(debugger: lldb.SBDebugger, _):
25+
target = debugger.GetDummyTarget()
26+
# Caveat: must use BreakpointCreateByRegEx here and not
27+
# BreakpointCreateByName. For some reasons callback function does not
28+
# get carried over from dummy target for the later.
29+
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
30+
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
31+
bp.SetAutoContinue(True)
32+
print("-- LLDB integration loaded --")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#
2+
# Generated file, do not edit.
3+
#
4+
5+
command script import --relative-to-command-file flutter_lldb_helper.py

example/lib/views/home/home_view.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class HomeView extends StatelessWidget {
1010
@override
1111
Widget build(BuildContext context) {
1212
return ScreenTypeLayout.builder2(
13-
breakpoints: ScreenBreakpoints(large: 650, small: 250),
13+
breakpoints: ScreenBreakpoints(small: 250, normal: 500, large: 650),
1414
desktop: (_, __) => HomeViewDesktop(),
1515
phone: (_, __) => OrientationLayoutBuilder(
1616
portrait: (context) => HomeMobileView(isPortrait: true),

lib/src/helpers/helpers.dart

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import 'package:flutter/widgets.dart';
55
import 'package:responsive_builder2/responsive_builder2.dart';
66
import 'package:universal_platform/universal_platform.dart';
77

8-
import 'device_width.dart' as width;
8+
import 'device_width.dart' if (dart.library.js_interop) 'device_width_web.dart'
9+
as width;
910

1011
/// Determines if the current platform is web or desktop (WASM compatible)
1112
final _isWebOrDesktop = kIsWeb ||
@@ -30,15 +31,23 @@ DeviceScreenType getDeviceType(Size size,
3031
isWebOrDesktop = isWebOrDesktop ??= _isWebOrDesktop;
3132
double deviceWidth = width.deviceWidth(size, isWebOrDesktop);
3233

33-
// Replaces the defaults with the user defined definitions
34+
// Use provided breakpoint with middle (normal) threshold
3435
if (breakpoint != null) {
35-
if (deviceWidth > breakpoint.large) {
36+
// Desktop or Tablet for very large widths
37+
if (deviceWidth >= breakpoint.large) {
3638
return _desktopOrTablet(isWebOrDesktop);
3739
}
3840

41+
// Watch for very small widths
3942
if (deviceWidth < breakpoint.small) {
4043
return DeviceScreenType.watch;
4144
}
45+
46+
// Classify phone/tablet using normal
47+
if (deviceWidth < breakpoint.normal) {
48+
return DeviceScreenType.phone;
49+
}
50+
return DeviceScreenType.tablet;
4251
}
4352

4453
if (deviceWidth >= ResponsiveSizingConfig.instance.breakpoints.large) {
@@ -49,7 +58,12 @@ DeviceScreenType getDeviceType(Size size,
4958
return DeviceScreenType.watch;
5059
}
5160

52-
return DeviceScreenType.phone;
61+
// Use global normal threshold
62+
final globalNormal = ResponsiveSizingConfig.instance.breakpoints.normal;
63+
if (deviceWidth < globalNormal) {
64+
return DeviceScreenType.phone;
65+
}
66+
return DeviceScreenType.tablet;
5367
}
5468

5569
/// Helper function to determine if a large screen should be treated as desktop
@@ -98,6 +112,9 @@ RefinedSize getRefinedSize(
98112
if (deviceWidth >= refinedBreakpoint.desktopNormal) {
99113
return RefinedSize.normal;
100114
}
115+
116+
// Below desktopNormal threshold
117+
return RefinedSize.small;
101118
}
102119

103120
if (deviceScreenType == DeviceScreenType.tablet) {
@@ -112,6 +129,9 @@ RefinedSize getRefinedSize(
112129
if (deviceWidth >= refinedBreakpoint.tabletNormal) {
113130
return RefinedSize.normal;
114131
}
132+
133+
// Below tabletNormal threshold
134+
return RefinedSize.small;
115135
}
116136

117137
if (deviceScreenType == DeviceScreenType.phone) {
@@ -126,6 +146,9 @@ RefinedSize getRefinedSize(
126146
if (deviceWidth >= refinedBreakpoint.mobileNormal) {
127147
return RefinedSize.normal;
128148
}
149+
150+
// Below mobileNormal threshold
151+
return RefinedSize.small;
129152
}
130153

131154
if (deviceScreenType == DeviceScreenType.watch) {

lib/src/responsive_sizing_config.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ class ResponsiveSizingConfig {
4545
/// * [small]: 300 logical pixels - devices below this width are considered
4646
/// mobile
4747
static const ScreenBreakpoints _defaultBreakPoints = ScreenBreakpoints(
48-
large: 600,
4948
small: 300,
49+
normal: 600,
50+
large: 950,
5051
);
5152

5253
/// Custom breakpoints that override the defaults when set.

lib/src/sizing_information.dart

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,27 +75,44 @@ class SizingInformation {
7575
/// Manually define screen resolution breakpoints for device type detection.
7676
///
7777
/// This class allows you to override the default breakpoints used to determine
78-
/// whether a device should be considered small (mobile) or large
79-
/// (tablet/desktop). The breakpoints are defined in logical pixels.
78+
/// whether a device should be considered a watch, phone, tablet, or desktop.
79+
/// The breakpoints are defined in logical pixels.
80+
///
81+
/// Behavior with three-tier classification when [normal] is provided:
82+
/// - width < [small] => watch
83+
/// - [small] <= width < [normal] => phone
84+
/// - [normal] <= width < [large] => tablet
85+
/// - width >= [large] => desktop or tablet (based on platform)
86+
///
87+
/// If [normal] is null, legacy two-tier behavior is used:
88+
/// - width < [small] => watch
89+
/// - [small] <= width < [large] => phone
90+
/// - width >= [large] => desktop or tablet (based on platform)
8091
class ScreenBreakpoints {
81-
/// The breakpoint below which a device is considered small (mobile)
92+
/// The breakpoint below which a device is considered a watch
8293
final double small;
8394

95+
/// The breakpoint between phone and tablet.
96+
///
97+
/// Values greater than or equal to [normal] and less than [large]
98+
/// will be considered tablet.
99+
final double normal;
100+
84101
/// The breakpoint above which a device is considered large (tablet/desktop)
85102
final double large;
86103

87104
/// Creates a new [ScreenBreakpoints] instance.
88105
///
89-
/// Both [small] and [large] parameters are required and should be specified
90-
/// in logical pixels.
106+
/// [small], [normal] and [large] are required and should be specified in logical pixels.
91107
const ScreenBreakpoints({
92108
required this.small,
109+
required this.normal,
93110
required this.large,
94111
});
95112

96113
@override
97114
String toString() {
98-
return "Large: $large, Small: $small";
115+
return "Large: $large, Normal: $normal, Small: $small";
99116
}
100117
}
101118

pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: responsive_builder2
22
description: A set of widgets that can be used to define a readable responsive UI for widgets.
3-
version: 0.8.7
3+
version: 0.8.8
44
homepage: https://github.com/Corkscrews/responsive_builder
55

66
funding:

0 commit comments

Comments
 (0)