summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/homescreen.dart3
-rw-r--r--lib/layout_size_helper.dart53
-rw-r--r--lib/page_dashboard.dart137
-rw-r--r--lib/page_home.dart34
-rw-r--r--lib/page_hvac.dart168
-rw-r--r--lib/page_media.dart85
6 files changed, 285 insertions, 195 deletions
diff --git a/lib/homescreen.dart b/lib/homescreen.dart
index efc622e..29702aa 100644
--- a/lib/homescreen.dart
+++ b/lib/homescreen.dart
@@ -1,5 +1,3 @@
-import 'dart:math';
-
import 'package:flutter/material.dart';
import 'package:flutter_homescreen/page_dashboard.dart';
import 'package:flutter_homescreen/page_home.dart';
@@ -59,6 +57,7 @@ class _HomescreenState extends State<Homescreen> with TickerProviderStateMixin {
}
Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
+ // size the icons so they cover the left edge of the screen
var iconSize = constraints.maxHeight / (PageIndex.values.length + 2);
var railSize = constraints.maxHeight / (PageIndex.values.length + 1);
diff --git a/lib/layout_size_helper.dart b/lib/layout_size_helper.dart
new file mode 100644
index 0000000..9cbb0d7
--- /dev/null
+++ b/lib/layout_size_helper.dart
@@ -0,0 +1,53 @@
+import 'package:flutter/material.dart';
+
+class LayoutSizeHelper {
+ Size _size;
+ double _ratio;
+
+ LayoutSizeHelper(context)
+ : _size = MediaQuery.of(context).size,
+ _ratio = MediaQuery.of(context).devicePixelRatio;
+
+ update(context) {
+ _size = MediaQuery.of(context).size;
+ _ratio = MediaQuery.of(context).devicePixelRatio;
+ }
+
+ get defaultIconSize {
+ if (_size.height <= 480 || _size.width <= 600) {
+ return 64.0 * _ratio;
+ } else if (_size.height <= 900 || _size.width <= 840) {
+ return 96.0 * _ratio;
+ } else {
+ return 128.0 * _ratio;
+ }
+ }
+
+ get defaultButtonHeight {
+ return defaultIconSize;
+ }
+
+ get defaultButtonWidth {
+ return defaultButtonHeight * 3.0;
+ }
+
+ get defaultPadding {
+ return defaultIconSize / 8.0;
+ }
+
+ get defaultBorder {
+ return defaultIconSize / 16;
+ }
+
+ get baseFontSize {
+ return (defaultIconSize / 3.0).floor().toDouble();
+ }
+
+ get largeIconSize {
+ return 1.5 * defaultIconSize;
+ }
+
+ get largePadding {
+ return largeIconSize / 4.0;
+ }
+}
diff --git a/lib/page_dashboard.dart b/lib/page_dashboard.dart
index 2ab1d38..172a38a 100644
--- a/lib/page_dashboard.dart
+++ b/lib/page_dashboard.dart
@@ -1,57 +1,68 @@
import 'package:flutter/material.dart';
+import 'package:flutter_homescreen/layout_size_helper.dart';
class DashboardPage extends StatelessWidget {
const DashboardPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
- var screenHeight = MediaQuery.of(context).size.height;
- var iconSize = screenHeight / 8;
-
+ var sizeHelper = LayoutSizeHelper(context);
return Container(
color: Colors.indigo.shade50,
constraints: BoxConstraints.expand(),
alignment: Alignment.center,
child: Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
+ mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text(
'0 kpm',
- style: Theme.of(context).textTheme.headline4,
+ style: Theme.of(context).textTheme.headline2,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
- Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- Text(
- 'Left front tire',
- style: Theme.of(context).textTheme.headline4,
- ),
- Text(
- 'Left rear tire',
- style: Theme.of(context).textTheme.headline4,
- ),
- ],
+ Expanded(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Text(
+ 'Left front tire',
+ style: Theme.of(context).textTheme.headline4,
+ ),
+ SizedBox(
+ height: sizeHelper.largeIconSize,
+ ),
+ Text(
+ 'Left rear tire',
+ style: Theme.of(context).textTheme.headline4,
+ ),
+ ],
+ ),
),
- Icon(
- Icons.drive_eta,
- size: iconSize,
- color: Colors.indigo.shade800,
+ Image.asset(
+ 'images/HMI_Dashboard_Car_720.png',
+ width: sizeHelper.largeIconSize,
+ fit: BoxFit.contain,
),
- Column(
- mainAxisAlignment: MainAxisAlignment.spaceAround,
- children: [
- Text(
- 'Right front tire',
- style: Theme.of(context).textTheme.headline4,
- ),
- Text(
- 'Right rear tire',
- style: Theme.of(context).textTheme.headline4,
- ),
- ],
+ Expanded(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ 'Right front tire',
+ style: Theme.of(context).textTheme.headline4,
+ ),
+ SizedBox(
+ height: sizeHelper.largeIconSize,
+ ),
+ Text(
+ 'Right rear tire',
+ style: Theme.of(context).textTheme.headline4,
+ ),
+ ],
+ ),
),
],
),
@@ -59,10 +70,7 @@ class DashboardPage extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
_RPMWidget(),
- Text(
- 'Fuel',
- style: Theme.of(context).textTheme.headline4,
- ),
+ _FuelWidget(),
],
)
],
@@ -71,22 +79,59 @@ class DashboardPage extends StatelessWidget {
}
}
-// ignore: unused_element
class _RPMWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Row(
- mainAxisAlignment: MainAxisAlignment.start,
+ var sizeHelper = LayoutSizeHelper(context);
+ return Stack(
+ alignment: Alignment.center,
children: [
- Icon(Icons.fastfood),
+ Text(
+ 'RPM',
+ style: Theme.of(context).textTheme.headline4,
+ ),
Container(
- height: 20,
- width: 70,
- child: LinearProgressIndicator(
- value: 0.75,
- semanticsLabel: 'Linear progress indicator',
+ height: sizeHelper.largeIconSize,
+ width: sizeHelper.largeIconSize,
+ margin: EdgeInsets.all(sizeHelper.largePadding),
+ child: RotatedBox(
+ quarterTurns: 2,
+ child: CircularProgressIndicator(
+ value: 0.75,
+ strokeWidth: sizeHelper.largeIconSize / 4.0,
+ semanticsLabel: 'RPM indicator',
+ ),
),
+ )
+ ],
+ );
+ }
+}
+
+class _FuelWidget extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ var sizeHelper = LayoutSizeHelper(context);
+ return Stack(
+ alignment: Alignment.center,
+ children: [
+ Text(
+ 'Fuel',
+ style: Theme.of(context).textTheme.headline4,
),
+ Container(
+ height: sizeHelper.largeIconSize,
+ width: sizeHelper.largeIconSize,
+ margin: EdgeInsets.all(sizeHelper.largePadding),
+ child: RotatedBox(
+ quarterTurns: 2,
+ child: CircularProgressIndicator(
+ value: 0.75,
+ strokeWidth: sizeHelper.largeIconSize / 4.0,
+ semanticsLabel: 'RPM indicator',
+ ),
+ ),
+ )
],
);
}
diff --git a/lib/page_home.dart b/lib/page_home.dart
index 1fbda1f..7b4bc79 100644
--- a/lib/page_home.dart
+++ b/lib/page_home.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:flutter_homescreen/layout_size_helper.dart';
class HomePage extends StatelessWidget {
final Function(int index) onSetNavigationIndex;
@@ -8,35 +9,34 @@ class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
- final double spacing = MediaQuery.of(context).size.width / 32;
- final double runSpacing = spacing / 2;
+ var themeHelper = LayoutSizeHelper(context);
return Container(
color: Colors.lightBlue.shade50,
constraints: BoxConstraints.expand(),
alignment: Alignment.center,
child: Wrap(
- spacing: spacing,
- runSpacing: runSpacing,
- children: <Widget>[
- createItem(context, Icons.drive_eta, 1),
- createItem(context, Icons.thermostat, 2),
- createItem(context, Icons.music_note, 3)
- ],
- ));
+ spacing: themeHelper.largePadding,
+ runSpacing: themeHelper.largePadding,
+ children: <Widget>[
+ createItem(themeHelper, Icons.drive_eta, 1),
+ createItem(themeHelper, Icons.thermostat, 2),
+ createItem(themeHelper, Icons.music_note, 3)
+ ],
+ ));
}
- Widget createItem(BuildContext context, IconData icon, int tabPosition) {
- final double size = MediaQuery.of(context).size.width / 6;
- final double padding = size / 4;
- final double border = padding / 4;
+ Widget createItem(
+ LayoutSizeHelper themeHelper, IconData icon, int tabPosition) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: OutlinedButton(
style: OutlinedButton.styleFrom(
shape: CircleBorder(),
- padding: EdgeInsets.all(padding),
+ padding: EdgeInsets.all(themeHelper.largePadding),
primary: Colors.lightBlue.shade400,
- side: BorderSide(width: border, color: Colors.lightBlue.shade400)
+ side: BorderSide(
+ width: themeHelper.defaultBorder,
+ color: Colors.lightBlue.shade400),
),
onPressed: () {
onSetNavigationIndex(tabPosition);
@@ -44,7 +44,7 @@ class HomePage extends StatelessWidget {
child: Icon(
icon,
color: Colors.lightBlue.shade800,
- size: size / 2,
+ size: themeHelper.largeIconSize,
),
),
);
diff --git a/lib/page_hvac.dart b/lib/page_hvac.dart
index ea6dd3b..d416a1b 100644
--- a/lib/page_hvac.dart
+++ b/lib/page_hvac.dart
@@ -1,6 +1,5 @@
-import 'dart:math';
-
import 'package:flutter/material.dart';
+import 'package:flutter_homescreen/layout_size_helper.dart';
import 'package:numberpicker/numberpicker.dart';
class HVACPageContainer extends StatelessWidget {
@@ -16,9 +15,7 @@ class HVACPageContainer extends StatelessWidget {
}
class _TemperatureSelector extends StatefulWidget {
-final double referenceFontSize = 24;
-
- _TemperatureSelector({Key? key, referenceFontSize}) : super(key: key);
+ _TemperatureSelector({Key? key}) : super(key: key);
@override
_TemperatureSelectorState createState() => _TemperatureSelectorState();
@@ -29,6 +26,7 @@ class _TemperatureSelectorState extends State<_TemperatureSelector> {
@override
Widget build(BuildContext context) {
+ var sizeHelper = LayoutSizeHelper(context);
return Column(
children: <Widget>[
NumberPicker(
@@ -38,14 +36,14 @@ class _TemperatureSelectorState extends State<_TemperatureSelector> {
onChanged: (value) => setState(() => _currentValue = value),
textStyle: DefaultTextStyle.of(context).style.copyWith(
color: Colors.teal.shade200,
- fontSize: widget.referenceFontSize,
+ fontSize: sizeHelper.baseFontSize,
),
selectedTextStyle: DefaultTextStyle.of(context).style.copyWith(
color: Colors.white,
- fontSize: widget.referenceFontSize * 1.5,
+ fontSize: sizeHelper.baseFontSize * 1.5,
),
- itemHeight: widget.referenceFontSize * 3,
- itemWidth: widget.referenceFontSize * 6,
+ itemHeight: sizeHelper.baseFontSize * 3,
+ itemWidth: sizeHelper.baseFontSize * 6,
),
],
);
@@ -72,16 +70,16 @@ class _HVACFanSpeedState extends State<HVACFanSpeed> {
inactiveTrackColor: Colors.blueGrey.shade200,
),
child: Slider(
- value: _currentSliderValue,
- min: 0,
- max: 300,
- label: _currentSliderValue.round().toString(),
- onChanged: (double value) {
- setState(() {
- _currentSliderValue = value;
- });
- },
- ),
+ value: _currentSliderValue,
+ min: 0,
+ max: 300,
+ label: _currentSliderValue.round().toString(),
+ onChanged: (double value) {
+ setState(() {
+ _currentSliderValue = value;
+ });
+ },
+ ),
);
}
}
@@ -102,82 +100,75 @@ bool selected = true; // Get from API
class _HVACPageState extends State<HVACPage> {
final double fanSpeed = 20;
- Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
- // describe the layout in terms of fractions of the container size
- double mainDimension = max(constraints.maxWidth, constraints.maxHeight);
- double minDimension = min(constraints.maxWidth, constraints.maxHeight);
- double iconSize = mainDimension / 12.0;
- double largeIconSize = mainDimension / 8.0;
- double spacingSize = minDimension / 48.0;
- double buttonWidth = constraints.maxWidth / 6.0;
- double buttonHeight = constraints.maxHeight / 6.0;
- double defaultFontSize = constraints.maxHeight / 24.0;
+ @override
+ Widget build(BuildContext context) {
+ var sizeHelper = LayoutSizeHelper(context);
TextStyle buttonTextStyle = DefaultTextStyle.of(context).style.copyWith(
color: Colors.white,
- fontSize: defaultFontSize,
+ fontSize: sizeHelper.baseFontSize,
);
Widget fanSpeedControl = Container(
padding: EdgeInsets.symmetric(
- vertical: spacingSize,
- horizontal: 3 * spacingSize,
+ vertical: sizeHelper.defaultPadding,
+ horizontal: 3.0 * sizeHelper.defaultPadding,
),
child: Row(
children: [
Expanded(flex: 4, child: const HVACFanSpeed()),
- SizedBox(width: spacingSize),
+ SizedBox(width: sizeHelper.defaultPadding),
Expanded(
flex: 1,
child: Image.asset('images/HMI_HVAC_Fan_Icon.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain)),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain)),
],
),
);
Widget rightSeat = Container(
- padding: EdgeInsets.all(spacingSize),
+ padding: EdgeInsets.all(sizeHelper.defaultPadding),
child: Column(
children: [
IconButton(
- iconSize: largeIconSize,
+ iconSize: sizeHelper.largeIconSize,
icon: Image.asset(selected ? chairOn : chairOff,
- width: largeIconSize,
- height: largeIconSize,
+ width: sizeHelper.largeIconSize,
+ height: sizeHelper.largeIconSize,
fit: BoxFit.contain),
onPressed: () {
selected = !selected;
},
),
- SizedBox(height: spacingSize),
- _TemperatureSelector(
- referenceFontSize: defaultFontSize,
- ),
+ SizedBox(height: sizeHelper.defaultPadding),
+ _TemperatureSelector(),
],
),
);
Widget leftSeat = Container(
- padding: EdgeInsets.all(spacingSize),
+ padding: EdgeInsets.all(sizeHelper.defaultPadding),
child: Column(
children: [
Image.asset('images/HMI_HVAC_Right_Chair_ON.png',
- width: largeIconSize, height: largeIconSize, fit: BoxFit.contain),
- SizedBox(height: spacingSize),
- _TemperatureSelector(
- referenceFontSize: defaultFontSize,
- ),
+ width: sizeHelper.largeIconSize,
+ height: sizeHelper.largeIconSize,
+ fit: BoxFit.contain),
+ SizedBox(height: sizeHelper.defaultPadding),
+ _TemperatureSelector(),
],
),
);
Widget centerView = Container(
- padding: EdgeInsets.all(spacingSize),
+ padding: EdgeInsets.all(sizeHelper.defaultPadding),
child: Column(
children: [
Container(
- width: buttonWidth,
- height: buttonHeight,
- margin: EdgeInsets.all(spacingSize),
+ width: sizeHelper.defaultButtonWidth,
+ height: sizeHelper.defaultButtonHeight,
+ margin: EdgeInsets.all(sizeHelper.defaultPadding),
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(20)),
@@ -189,9 +180,9 @@ class _HVACPageState extends State<HVACPage> {
),
),
Container(
- width: buttonWidth,
- height: buttonHeight,
- margin: EdgeInsets.all(spacingSize),
+ width: sizeHelper.defaultButtonWidth,
+ height: sizeHelper.defaultButtonHeight,
+ margin: EdgeInsets.all(sizeHelper.defaultPadding),
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(20)),
@@ -203,9 +194,9 @@ class _HVACPageState extends State<HVACPage> {
),
),
Container(
- width: buttonWidth,
- height: buttonHeight,
- margin: EdgeInsets.all(spacingSize),
+ width: sizeHelper.defaultButtonWidth,
+ height: sizeHelper.defaultButtonHeight,
+ margin: EdgeInsets.all(sizeHelper.defaultPadding),
decoration: BoxDecoration(
border: Border.all(color: Colors.green),
borderRadius: BorderRadius.circular(20)),
@@ -214,56 +205,57 @@ class _HVACPageState extends State<HVACPage> {
// Respond to button press
},
child: Image.asset('images/HMI_HVAC_Circulation_Inactive.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain)),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain)),
),
],
),
);
Widget actions = Container(
- padding: EdgeInsets.all(spacingSize),
+ padding: EdgeInsets.all(sizeHelper.defaultPadding),
child: Column(
children: [
Image.asset('images/HMI_HVAC_AirDown_Inactive.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain),
- SizedBox(height: spacingSize),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain),
+ SizedBox(height: sizeHelper.defaultPadding),
Image.asset('images/HMI_HVAC_AirUp_Inactive.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain),
- SizedBox(height: spacingSize),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain),
+ SizedBox(height: sizeHelper.defaultPadding),
Image.asset('images/HMI_HVAC_Front_Inactive.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain),
- SizedBox(height: spacingSize),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain),
+ SizedBox(height: sizeHelper.defaultPadding),
Image.asset('images/HMI_HVAC_Rear_Active.png',
- width: iconSize, height: iconSize, fit: BoxFit.contain),
+ width: sizeHelper.defaultIconSize,
+ height: sizeHelper.defaultIconSize,
+ fit: BoxFit.contain),
],
-
),
);
- return Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: <Widget>[
- fanSpeedControl,
- Row(children: [
- Expanded(flex: 1, child: rightSeat),
- Expanded(flex: 1, child: centerView),
- Expanded(flex: 1, child: leftSeat),
- Expanded(flex: 1, child: actions)
- ])
- ],
- );
- }
-
- @override
- Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topRight,
end: Alignment.bottomLeft,
colors: [Colors.blueGrey.shade900, Colors.grey.shade900])),
- child: Center(
- child: LayoutBuilder(
- builder: _buildLayout,
- )));
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget>[
+ fanSpeedControl,
+ Row(children: [
+ Expanded(flex: 1, child: rightSeat),
+ Expanded(flex: 1, child: centerView),
+ Expanded(flex: 1, child: leftSeat),
+ Expanded(flex: 1, child: actions)
+ ])
+ ],
+ ));
}
}
diff --git a/lib/page_media.dart b/lib/page_media.dart
index f87f20b..618feb3 100644
--- a/lib/page_media.dart
+++ b/lib/page_media.dart
@@ -1,17 +1,37 @@
-import 'dart:math';
-
import 'package:flutter/material.dart';
+import 'package:flutter_homescreen/layout_size_helper.dart';
class MediaPage extends StatelessWidget {
const MediaPage({Key? key}) : super(key: key);
- Widget _buildLayout(BuildContext context, BoxConstraints constraints) {
- // describe the layout in terms of fractions of the container size
- double mainDimension = max(constraints.maxWidth, constraints.maxHeight);
- //double minDimension = min(constraints.maxWidth, constraints.maxHeight);
- double iconSize = mainDimension / 12.0;
+ Widget _createMediaButton(
+ IconData icon, double iconSize, Null Function() onPressed) {
+ return Padding(
+ padding: EdgeInsets.all(iconSize / 8),
+ child: ElevatedButton(
+ onPressed: onPressed,
+ child: Icon(
+ icon,
+ color: Colors.blueGrey.shade700,
+ size: iconSize,
+ ),
+ style: ElevatedButton.styleFrom(
+ shape: CircleBorder(),
+ padding: EdgeInsets.all(iconSize / 8),
+ primary: Colors.blueGrey.shade100,
+ onPrimary: Colors.white,
+ ),
+ ),
+ );
+ }
+ @override
+ Widget build(BuildContext context) {
+ var sizeHelper = LayoutSizeHelper(context);
return Container(
+ color: Colors.deepPurple.shade50,
+ child: Center(
+ child: Container(
color: Colors.blueGrey.shade900,
constraints: BoxConstraints.expand(),
alignment: Alignment.center,
@@ -34,44 +54,25 @@ class MediaPage extends StatelessWidget {
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
- _createMediaButton(Icons.skip_previous, iconSize, () {}),
- _createMediaButton(Icons.play_arrow, iconSize, () {}),
- _createMediaButton(Icons.skip_next, iconSize, () {}),
+ _createMediaButton(
+ Icons.skip_previous,
+ sizeHelper.defaultIconSize,
+ () {},
+ ),
+ _createMediaButton(
+ Icons.play_arrow,
+ sizeHelper.defaultIconSize,
+ () {},
+ ),
+ _createMediaButton(
+ Icons.skip_next,
+ sizeHelper.defaultIconSize,
+ () {},
+ ),
],
)
],
),
- );
- }
-
- Widget _createMediaButton(
- IconData icon, double iconSize, Null Function() onPressed) {
- return Padding(
- padding: EdgeInsets.all(iconSize / 8),
- child: ElevatedButton(
- onPressed: onPressed,
- child: Icon(
- icon,
- color: Colors.blueGrey.shade700,
- size: iconSize,
- ),
- style: ElevatedButton.styleFrom(
- shape: CircleBorder(),
- padding: EdgeInsets.all(iconSize / 8),
- primary: Colors.blueGrey.shade100,
- onPrimary: Colors.white,
- ),
- ),
- );
- }
-
- @override
- Widget build(BuildContext context) {
- return Container(
- color: Colors.deepPurple.shade50,
- child: Center(
- child: LayoutBuilder(
- builder: _buildLayout,
- )));
+ )));
}
}