Skip to content

Instantly share code, notes, and snippets.

@g-apparence
Created July 2, 2024 17:10
Show Gist options
  • Save g-apparence/b6d58fe8e8978f7c22cde2c8c9f6dcd0 to your computer and use it in GitHub Desktop.
Save g-apparence/b6d58fe8e8978f7c22cde2c8c9f6dcd0 to your computer and use it in GitHub Desktop.
A responsive flutter builder
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