flutter_orientation_builder.dart
复制代码
class $1 extends StatefulWidget {
const $1();
@override
_$2 createState() => _$2();
}
class $2 extends State<$1> {
const $2();
Widget build(BuildContext context) {
return Padding(
padding: EdgeInsets.only(top: 16.0),
child: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
if (orientation == Orientation.portrait) {
return OrientationPortrait();
} else {
return OrientationLandscape();
}
},
),
);
}
}
flutter_orientation_builder_example.dart
复制代码
import 'package:flutter/material.dart';
import 'package:meta/meta.dart';
import 'category.dart';
import 'unit.dart';
const _padding = EdgeInsets.all(16.0);
class UnitConverter extends StatefulWidget {
final Category category;
const UnitConverter({
@required this.category,
}) : assert(category != null);
@override
_UnitConverterState createState() => _UnitConverterState();
}
class _UnitConverterState extends State<UnitConverter> {
Unit _fromValue;
Unit _toValue;
double _inputValue;
String _convertedValue = '';
List<DropdownMenuItem> _unitMenuItems;
bool _showValidationError = false;
final _inputKey = GlobalKey(debugLabel: 'inputText');
@override
void initState() {
super.initState();
_createDropdownMenuItems();
_setDefaults();
}
@override
void didUpdateWidget(UnitConverter old) {
super.didUpdateWidget(old);
if (old.category != widget.category) {
_createDropdownMenuItems();
_setDefaults();
}
}
void _createDropdownMenuItems() {
var newItems = <DropdownMenuItem>[];
for (var unit in widget.category.units) {
newItems.add(DropdownMenuItem(
value: unit.name,
child: Container(
child: Text(
unit.name,
softWrap: true,
),
),
));
}
setState(() {
_unitMenuItems = newItems;
});
}
void _setDefaults() {
setState(() {
_fromValue = widget.category.units[0];
_toValue = widget.category.units[1];
});
if (_inputValue != null) {
_updateConversion();
}
}
String _format(double conversion) {
var outputNum = conversion.toStringAsPrecision(7);
if (outputNum.contains('.') && outputNum.endsWith('0')) {
var i = outputNum.length - 1;
while (outputNum[i] == '0') {
i -= 1;
}
outputNum = outputNum.substring(0, i + 1);
}
if (outputNum.endsWith('.')) {
return outputNum.substring(0, outputNum.length - 1);
}
return outputNum;
}
void _updateConversion() {
setState(() {
_convertedValue =
_format(_inputValue * (_toValue.conversion / _fromValue.conversion));
});
}
void _updateInputValue(String input) {
setState(() {
if (input == null || input.isEmpty) {
_convertedValue = '';
} else {
try {
final inputDouble = double.parse(input);
_showValidationError = false;
_inputValue = inputDouble;
_updateConversion();
} on Exception catch (e) {
print('Error: $e');
_showValidationError = true;
}
}
});
}
Unit _getUnit(String unitName) {
return widget.category.units.firstWhere(
(Unit unit) {
return unit.name == unitName;
},
orElse: null,
);
}
void _updateFromConversion(dynamic unitName) {
setState(() {
_fromValue = _getUnit(unitName);
});
if (_inputValue != null) {
_updateConversion();
}
}
void _updateToConversion(dynamic unitName) {
setState(() {
_toValue = _getUnit(unitName);
});
if (_inputValue != null) {
_updateConversion();
}
}
Widget _createDropdown(String currentValue, ValueChanged<dynamic> onChanged) {
return Container(
margin: EdgeInsets.only(top: 16.0),
decoration: BoxDecoration(
// This sets the color of the [DropdownButton] itself
color: Colors.grey[50],
border: Border.all(
color: Colors.grey[400],
width: 1.0,
),
),
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Theme(
// This sets the color of the [DropdownMenuItem]
data: Theme.of(context).copyWith(
canvasColor: Colors.grey[50],
),
child: DropdownButtonHideUnderline(
child: ButtonTheme(
alignedDropdown: true,
child: DropdownButton(
value: currentValue,
items: _unitMenuItems,
onChanged: onChanged,
style: Theme.of(context).textTheme.title,
),
),
),
),
);
}
@override
Widget build(BuildContext context) {
final input = Padding(
padding: _padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
TextField(
key: _inputKey,
style: Theme.of(context).textTheme.display1,
decoration: InputDecoration(
labelStyle: Theme.of(context).textTheme.display1,
errorText: _showValidationError ? 'Invalid number entered' : null,
labelText: 'Input',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
),
),
keyboardType: TextInputType.number,
onChanged: _updateInputValue,
),
_createDropdown(_fromValue.name, _updateFromConversion),
],
),
);
final arrows = RotatedBox(
quarterTurns: 1,
child: Icon(
Icons.compare_arrows,
size: 40.0,
),
);
final output = Padding(
padding: _padding,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
InputDecorator(
child: Text(
_convertedValue,
style: Theme.of(context).textTheme.display1,
),
decoration: InputDecoration(
labelText: 'Output',
labelStyle: Theme.of(context).textTheme.display1,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(0.0),
),
),
),
_createDropdown(_toValue.name, _updateToConversion),
],
),
);
final converter = ListView(
children: [
input,
arrows,
output,
],
);
return Padding(
padding: _padding,
child: OrientationBuilder(
builder: (BuildContext context, Orientation orientation) {
if (orientation == Orientation.portrait) {
return converter;
} else {
return Center(
child: Container(
width: 450.0,
child: converter,
),
);
}
},
),
);
}
}
flutter_orientation_mediaquery.dart
复制代码
class $1 extends StatefulWidget {
const $1();
@override
_$2 createState() => _$2();
}
class $2 extends State<$1> {
const $2();
Widget _buildMyWidgets(Orientation deviceOrientation) {
if (deviceOrientation == Orientation.portrait) {
return OrientationPortrait();
} else {
return OrientationLandscape();
}
}
Widget build(BuildContext context) {
return _buildMyWidgets(MediaQuery.of(context).orientation);
}
}
flutter_orientation_mediaquery_example.dart
复制代码
import 'package:flutter/material.dart';
import 'backdrop.dart';
import 'category.dart';
import 'category_tile.dart';
import 'unit.dart';
import 'unit_converter.dart';
class CategoryRoute extends StatefulWidget {
const CategoryRoute();
@override
_CategoryRouteState createState() => _CategoryRouteState();
}
class _CategoryRouteState extends State<CategoryRoute> {
Category _defaultCategory;
Category _currentCategory;
final _categories = <Category>[];
static const _categoryNames = <String>[
'Length',
'Area',
'Volume',
'Mass',
'Time',
'Digital Storage',
'Energy',
'Currency',
];
static const _baseColors = <ColorSwatch>[
ColorSwatch(0xFF6AB7A8, {
'highlight': Color(0xFF6AB7A8),
'splash': Color(0xFF0ABC9B),
}),
ColorSwatch(0xFFFFD28E, {
'highlight': Color(0xFFFFD28E),
'splash': Color(0xFFFFA41C),
}),
ColorSwatch(0xFFFFB7DE, {
'highlight': Color(0xFFFFB7DE),
'splash': Color(0xFFF94CBF),
}),
ColorSwatch(0xFF8899A8, {
'highlight': Color(0xFF8899A8),
'splash': Color(0xFFA9CAE8),
}),
ColorSwatch(0xFFEAD37E, {
'highlight': Color(0xFFEAD37E),
'splash': Color(0xFFFFE070),
}),
ColorSwatch(0xFF81A56F, {
'highlight': Color(0xFF81A56F),
'splash': Color(0xFF7CC159),
}),
ColorSwatch(0xFFD7C0E2, {
'highlight': Color(0xFFD7C0E2),
'splash': Color(0xFFCA90E5),
}),
ColorSwatch(0xFFCE9A9A, {
'highlight': Color(0xFFCE9A9A),
'splash': Color(0xFFF94D56),
'error': Color(0xFF912D2D),
}),
];
@override
void initState() {
super.initState();
for (var i = 0; i < _categoryNames.length; i++) {
var category = Category(
name: _categoryNames[i],
color: _baseColors[i],
iconLocation: Icons.cake,
units: _retrieveUnitList(_categoryNames[i]),
);
if (i == 0) {
_defaultCategory = category;
}
_categories.add(category);
}
}
void _onCategoryTap(Category category) {
setState(() {
_currentCategory = category;
});
}
Widget _buildCategoryWidgets(Orientation deviceOrientation) {
if (deviceOrientation == Orientation.portrait) {
return ListView.builder(
itemBuilder: (BuildContext context, int index) {
return CategoryTile(
category: _categories[index],
onTap: _onCategoryTap,
);
},
itemCount: _categories.length,
);
} else {
return GridView.count(
crossAxisCount: 2,
childAspectRatio: 3.0,
children: _categories.map((Category c) {
return CategoryTile(
category: c,
onTap: _onCategoryTap,
);
}).toList(),
);
}
}
List<Unit> _retrieveUnitList(String categoryName) {
return List.generate(10, (int i) {
i += 1;
return Unit(
name: '$categoryName Unit $i',
conversion: i.toDouble(),
);
});
}
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
final listView = Padding(
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
bottom: 48.0,
),
child: _buildCategoryWidgets(MediaQuery.of(context).orientation),
);
return Backdrop(
currentCategory:
_currentCategory == null ? _defaultCategory : _currentCategory,
frontPanel: _currentCategory == null
? UnitConverter(category: _defaultCategory)
: UnitConverter(category: _currentCategory),
backPanel: listView,
frontTitle: Text('Unit Converter'),
backTitle: Text('Select a Category'),
);
}
}