Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.8.8

- Make `ScreenBreakpoints.normal` mandatory (small/normal/large) and improve device detection (watch/phone/tablet/desktop).

## 0.8.7

- Similar to 0.8.6 with changes to the `README.md`.
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ It aims to provide you with widgets that make it easy to build different UI's al
Add responsive_builder as dependency to your pubspec file.

```
responsive_builder2: ^0.8.7
responsive_builder2: ^0.8.8
```

## Usage
Expand Down Expand Up @@ -167,9 +167,9 @@ import 'package:responsive_builder2/responsive_builder2.dart';
//ScreenTypeLayout with custom breakpoints supplied
ScreenTypeLayout(
breakpoints: ScreenBreakpoints(
tablet: 600,
desktop: 950,
watch: 300
small: 300,
normal: 600,
large: 950,
),
mobile: Container(color:Colors.blue),
tablet: Container(color: Colors.yellow),
Expand All @@ -187,7 +187,7 @@ If you want to set the breakpoints for the responsive builders once you can call
```dart
void main() {
ResponsiveSizingConfig.instance.setCustomBreakpoints(
ScreenBreakpoints(large: 550, small: 200),
ScreenBreakpoints(small: 200, normal: 550, large: 1000),
);
runApp(MyApp());
}
Expand Down
32 changes: 32 additions & 0 deletions example/ios/Flutter/ephemeral/flutter_lldb_helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#
# Generated file, do not edit.
#

import lldb

def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
base = frame.register["x0"].GetValueAsAddress()
page_len = frame.register["x1"].GetValueAsUnsigned()

# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
# first page to see if handled it correctly. This makes diagnosing
# misconfiguration (e.g. missing breakpoint) easier.
data = bytearray(page_len)
data[0:8] = b'IHELPED!'

error = lldb.SBError()
frame.GetThread().GetProcess().WriteMemory(base, data, error)
if not error.Success():
print(f'Failed to write into {base}[+{page_len}]', error)
return

def __lldb_init_module(debugger: lldb.SBDebugger, _):
target = debugger.GetDummyTarget()
# Caveat: must use BreakpointCreateByRegEx here and not
# BreakpointCreateByName. For some reasons callback function does not
# get carried over from dummy target for the later.
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
bp.SetAutoContinue(True)
print("-- LLDB integration loaded --")
5 changes: 5 additions & 0 deletions example/ios/Flutter/ephemeral/flutter_lldbinit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#
# Generated file, do not edit.
#

command script import --relative-to-command-file flutter_lldb_helper.py
2 changes: 1 addition & 1 deletion example/lib/views/home/home_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class HomeView extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ScreenTypeLayout.builder2(
breakpoints: ScreenBreakpoints(large: 650, small: 250),
breakpoints: ScreenBreakpoints(small: 250, normal: 500, large: 650),
desktop: (_, __) => HomeViewDesktop(),
phone: (_, __) => OrientationLayoutBuilder(
portrait: (context) => HomeMobileView(isPortrait: true),
Expand Down
31 changes: 27 additions & 4 deletions lib/src/helpers/helpers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import 'package:flutter/widgets.dart';
import 'package:responsive_builder2/responsive_builder2.dart';
import 'package:universal_platform/universal_platform.dart';

import 'device_width.dart' as width;
import 'device_width.dart' if (dart.library.js_interop) 'device_width_web.dart'
as width;

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

// Replaces the defaults with the user defined definitions
// Use provided breakpoint with middle (normal) threshold
if (breakpoint != null) {
if (deviceWidth > breakpoint.large) {
// Desktop or Tablet for very large widths
if (deviceWidth >= breakpoint.large) {
return _desktopOrTablet(isWebOrDesktop);
}

// Watch for very small widths
if (deviceWidth < breakpoint.small) {
return DeviceScreenType.watch;
}

// Classify phone/tablet using normal
if (deviceWidth < breakpoint.normal) {
return DeviceScreenType.phone;
}
return DeviceScreenType.tablet;
}

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

return DeviceScreenType.phone;
// Use global normal threshold
final globalNormal = ResponsiveSizingConfig.instance.breakpoints.normal;
if (deviceWidth < globalNormal) {
return DeviceScreenType.phone;
}
return DeviceScreenType.tablet;
}

/// Helper function to determine if a large screen should be treated as desktop
Expand Down Expand Up @@ -98,6 +112,9 @@ RefinedSize getRefinedSize(
if (deviceWidth >= refinedBreakpoint.desktopNormal) {
return RefinedSize.normal;
}

// Below desktopNormal threshold
return RefinedSize.small;
}

if (deviceScreenType == DeviceScreenType.tablet) {
Expand All @@ -112,6 +129,9 @@ RefinedSize getRefinedSize(
if (deviceWidth >= refinedBreakpoint.tabletNormal) {
return RefinedSize.normal;
}

// Below tabletNormal threshold
return RefinedSize.small;
}

if (deviceScreenType == DeviceScreenType.phone) {
Expand All @@ -126,6 +146,9 @@ RefinedSize getRefinedSize(
if (deviceWidth >= refinedBreakpoint.mobileNormal) {
return RefinedSize.normal;
}

// Below mobileNormal threshold
return RefinedSize.small;
}

if (deviceScreenType == DeviceScreenType.watch) {
Expand Down
3 changes: 2 additions & 1 deletion lib/src/responsive_sizing_config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,9 @@ class ResponsiveSizingConfig {
/// * [small]: 300 logical pixels - devices below this width are considered
/// mobile
static const ScreenBreakpoints _defaultBreakPoints = ScreenBreakpoints(
large: 600,
small: 300,
normal: 600,
large: 950,
);

/// Custom breakpoints that override the defaults when set.
Expand Down
29 changes: 23 additions & 6 deletions lib/src/sizing_information.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,27 +75,44 @@ class SizingInformation {
/// Manually define screen resolution breakpoints for device type detection.
///
/// This class allows you to override the default breakpoints used to determine
/// whether a device should be considered small (mobile) or large
/// (tablet/desktop). The breakpoints are defined in logical pixels.
/// whether a device should be considered a watch, phone, tablet, or desktop.
/// The breakpoints are defined in logical pixels.
///
/// Behavior with three-tier classification when [normal] is provided:
/// - width < [small] => watch
/// - [small] <= width < [normal] => phone
/// - [normal] <= width < [large] => tablet
/// - width >= [large] => desktop or tablet (based on platform)
///
/// If [normal] is null, legacy two-tier behavior is used:
/// - width < [small] => watch
/// - [small] <= width < [large] => phone
/// - width >= [large] => desktop or tablet (based on platform)
class ScreenBreakpoints {
/// The breakpoint below which a device is considered small (mobile)
/// The breakpoint below which a device is considered a watch
final double small;

/// The breakpoint between phone and tablet.
///
/// Values greater than or equal to [normal] and less than [large]
/// will be considered tablet.
final double normal;

/// The breakpoint above which a device is considered large (tablet/desktop)
final double large;

/// Creates a new [ScreenBreakpoints] instance.
///
/// Both [small] and [large] parameters are required and should be specified
/// in logical pixels.
/// [small], [normal] and [large] are required and should be specified in logical pixels.
const ScreenBreakpoints({
required this.small,
required this.normal,
required this.large,
});

@override
String toString() {
return "Large: $large, Small: $small";
return "Large: $large, Normal: $normal, Small: $small";
}
}

Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: responsive_builder2
description: A set of widgets that can be used to define a readable responsive UI for widgets.
version: 0.8.7
version: 0.8.8
homepage: https://github.com/Corkscrews/responsive_builder

funding:
Expand Down
Loading