Created
July 2, 2024 17:10
-
-
Save g-apparence/b6d58fe8e8978f7c22cde2c8c9f6dcd0 to your computer and use it in GitHub Desktop.
A responsive flutter builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/widgets.dart'; | |
enum DeviceType { | |
small(0), | |
medium(768), | |
large(1024), | |
xlarge(1280); | |
final int breakpoint; | |
const DeviceType(this.breakpoint); | |
static DeviceType fromWidth(double width) { | |
return switch (width) { | |
< 768 => DeviceType.small, | |
< 1024 => DeviceType.medium, | |
< 1280 => DeviceType.large, | |
_ => DeviceType.xlarge, | |
}; | |
} | |
} | |
// ------------------------------------------------------ | |
// -- DeviceSizeBuilder | |
// ------------------------------------------------------ | |
typedef DeviceTypeBuilder = Widget Function(DeviceType); | |
/// A widget that helps you adapt content to the current device type. | |
/// It uses the Most upper View to get the current device width | |
/// A builder is provided to let you adapt the content to the current device type. | |
/// It will rebuild the content when the device type changes. | |
class DeviceSizeBuilder extends StatefulWidget { | |
final DeviceTypeBuilder builder; | |
const DeviceSizeBuilder({ | |
super.key, | |
required this.builder, | |
}); | |
@override | |
State<DeviceSizeBuilder> createState() => _DeviceSizeBuilderState(); | |
} | |
class _DeviceSizeBuilderState extends State<DeviceSizeBuilder> | |
with WidgetsBindingObserver { | |
late DeviceType _lastSize; | |
WidgetsBinding get widgetBinding => WidgetsBinding.instance; | |
@override | |
void initState() { | |
super.initState(); | |
widgetBinding.addObserver(this); | |
} | |
@override | |
void dispose() { | |
widgetBinding.removeObserver(this); | |
super.dispose(); | |
} | |
// detect the viewport width | |
// I don't use View.of(context).physicalSize.width; | |
// because it returns the complete screen width on Web | |
double get viewportWidth => MediaQuery.of(context).size.width; | |
@override | |
void didChangeDependencies() { | |
super.didChangeDependencies(); | |
_lastSize = DeviceType.fromWidth(viewportWidth); | |
} | |
@override | |
void didChangeMetrics() { | |
final newSize = DeviceType.fromWidth(viewportWidth); | |
if (_lastSize != newSize) { | |
_lastSize = newSize; | |
setState(() {}); | |
} | |
} | |
@override | |
Widget build(BuildContext context) { | |
return widget.builder(_lastSize); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment