get_responsive.dart
4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
import 'package:flutter/widgets.dart';
import '../../../get.dart';
import 'get_view.dart';
abstract class _GetResponsive<T> extends GetView<T> {
final ResponsiveScreen screen;
_GetResponsive(ResponsiveScreenSettings settings, {Key? key})
: screen = ResponsiveScreen(settings),
super(key: key);
Widget? builder();
Widget? phone();
Widget? tablet();
Widget? desktop();
Widget? watch();
}
/// Extend this widget to build responsive view.
/// this widget contains the `screen` property that have all
/// information about the screen size and type.
/// You have two options to build it.
/// 1- with `builder` method you return the widget to build.
/// 2- with methods `desktop`, `tablet`,`phone`, `watch`. the specific
/// method will be built when the screen type matches the method
/// when the screen is [ScreenType.Tablet] the `tablet` method
/// will be exuded and so on.
/// Note if you use this method please set the
/// property `alwaysUseBuilder` to false
/// With `settings` property you can set the width limit for the screen types.
class GetResponsiveView<T> extends _GetResponsive<T> {
final bool alwaysUseBuilder = true;
GetResponsiveView(
{alwaysUseBuilder,
ResponsiveScreenSettings settings = const ResponsiveScreenSettings(),
Key? key})
: super(settings, key: key);
@override
Widget build(BuildContext context) {
screen.context = context;
Widget? widget;
if (alwaysUseBuilder) {
widget = builder();
if (widget != null) return widget;
}
if (screen.isDesktop) {
widget = desktop() ?? widget;
if (widget != null) return widget;
}
if (screen.isTablet) {
widget = tablet() ?? desktop();
if (widget != null) return widget;
}
if (screen.isPhone) {
widget = phone() ?? tablet() ?? desktop();
if (widget != null) return widget;
}
return watch() ?? phone() ?? tablet() ?? desktop() ?? builder()!;
}
@override
Widget? builder() => null;
@override
Widget? desktop() => null;
@override
Widget? phone() => null;
@override
Widget? tablet() => null;
@override
Widget? watch() => null;
}
class ResponsiveScreenSettings {
/// When the width is greater als this value
/// the display will be set as [ScreenType.Desktop]
final double desktopChangePoint;
/// When the width is greater als this value
/// the display will be set as [ScreenType.Tablet]
/// or when width greater als [watchChangePoint] and smaller als this value
/// the display will be [ScreenType.Phone]
final double tabletChangePoint;
/// When the width is smaller als this value
/// the display will be set as [ScreenType.Watch]
/// or when width greater als this value and smaller als [tabletChangePoint]
/// the display will be [ScreenType.Phone]
final double watchChangePoint;
const ResponsiveScreenSettings(
{this.desktopChangePoint = 1200,
this.tabletChangePoint = 600,
this.watchChangePoint = 300});
}
class ResponsiveScreen {
late BuildContext context;
final ResponsiveScreenSettings settings;
late bool _isPaltformDesktop;
ResponsiveScreen(this.settings) {
_isPaltformDesktop = GetPlatform.isDesktop;
}
double get height => context.height;
double get width => context.width;
/// Is [screenType] [ScreenType.Desktop]
bool get isDesktop => (screenType == ScreenType.Desktop);
/// Is [screenType] [ScreenType.Tablet]
bool get isTablet => (screenType == ScreenType.Tablet);
/// Is [screenType] [ScreenType.Phone]
bool get isPhone => (screenType == ScreenType.Phone);
/// Is [screenType] [ScreenType.Watch]
bool get isWatch => (screenType == ScreenType.Watch);
double get _getdeviceWidth {
if (_isPaltformDesktop) {
return width;
}
return context.mediaQueryShortestSide;
}
ScreenType get screenType {
final deviceWidth = _getdeviceWidth;
if (deviceWidth >= settings.desktopChangePoint) return ScreenType.Desktop;
if (deviceWidth >= settings.tabletChangePoint) return ScreenType.Tablet;
if (deviceWidth < settings.watchChangePoint) return ScreenType.Watch;
return ScreenType.Phone;
}
/// Return widget according to screen type
/// if the [screenType] is [ScreenType.Desktop] and
/// `desktop` object is null the `tablet` object will be returned
/// and if `tablet` object is null the `mobile` object will be returned
/// and if `mobile` object is null the `watch` object will be returned
/// also when it is null.
T? responsiveValue<T>({
T? mobile,
T? tablet,
T? desktop,
T? watch,
}) {
if (isDesktop && desktop != null) return desktop;
if (isTablet && tablet != null) return tablet;
if (isPhone && mobile != null) return mobile;
return watch;
}
}
enum ScreenType {
Watch,
Phone,
Tablet,
Desktop,
}