Instantly share code, notes, and snippets.
Created
February 27, 2021 17:21
-
Star
(0)
0
You must be signed in to star a gist -
Fork
(0)
0
You must be signed in to fork a gist
-
Save tanabe1478/51dc6269df12010b828467edbbbc5274 to your computer and use it in GitHub Desktop.
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 'dart:io'; | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/material.dart'; | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
// This widget is the root of your application. | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
visualDensity: VisualDensity.adaptivePlatformDensity, | |
), | |
home: MyHomePage(title: 'Flutter Demo Home Page'), | |
); | |
} | |
} | |
class MyHomePage extends StatefulWidget { | |
MyHomePage({Key key, this.title}) : super(key: key); | |
final String title; | |
@override | |
_MyHomePageState createState() => _MyHomePageState(); | |
} | |
class _MyHomePageState extends State<MyHomePage> { | |
List<String> _strings = [ | |
"年", | |
"月", | |
"日", | |
]; | |
String _selectedString = "年"; | |
int _selectedRange = 1; | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(widget.title), | |
), | |
body: Center( | |
child: CycleSelectButtons( | |
selectedSpan: SpanExt.initFrom(_selectedString), | |
range: _selectedRange, | |
onSpanChanged: (value) { | |
setState(() { | |
_selectedString = value; | |
}); | |
}, | |
onRangeChanged: (value) { | |
print(value); | |
setState(() { | |
_selectedRange = value; | |
}); | |
}, | |
), | |
), | |
); | |
} | |
} | |
class AdaptiveDropdown extends StatelessWidget { | |
final List<String> itemStrings; | |
final String selectedItemString; | |
final ValueChanged<String> onChanged; | |
AdaptiveDropdown({this.itemStrings, this.selectedItemString, this.onChanged}) | |
: assert(itemStrings != null), | |
assert(selectedItemString != null), | |
assert(onChanged != null); | |
@override | |
Widget build(BuildContext context) { | |
return Platform.isIOS | |
? _buildCupertinoPicker(context) | |
: _buildDropDownButton(); | |
} | |
Widget _buildCupertinoPicker(BuildContext context) { | |
return Container( | |
child: Center( | |
child: CupertinoButton( | |
child: Text( | |
selectedItemString, | |
textAlign: TextAlign.center, | |
style: TextStyle(color: Colors.blue), | |
), | |
onPressed: () => _showModalPicker(context), | |
), | |
), | |
); | |
} | |
void _showModalPicker(BuildContext context) { | |
showModalBottomSheet( | |
context: context, | |
builder: (BuildContext context) { | |
return Container( | |
height: MediaQuery.of(context).size.height / 3, | |
child: GestureDetector( | |
onTap: () { | |
Navigator.pop(context); | |
}, | |
child: CupertinoPicker( | |
itemExtent: 40, | |
children: itemStrings.map(_pickerItem).toList(), | |
onSelectedItemChanged: (value) { | |
onChanged(itemStrings[value]); | |
}, | |
), | |
), | |
); | |
}, | |
); | |
} | |
Widget _pickerItem(String string) { | |
return Text( | |
string, | |
); | |
} | |
Widget _buildDropDownButton() { | |
return Padding( | |
padding: const EdgeInsets.only(left: 10.0), | |
child: DropdownButton( | |
value: selectedItemString, | |
icon: Icon(Icons.arrow_drop_down), | |
iconSize: 30, | |
elevation: 16, | |
underline: Container( | |
height: 2, | |
color: Colors.grey, | |
), | |
onChanged: onChanged, | |
items: itemStrings.map((String itemString) { | |
return DropdownMenuItem( | |
value: itemString, | |
child: Text( | |
itemString, | |
), | |
); | |
}).toList(), | |
), | |
); | |
} | |
} | |
class CycleSelectButtons extends StatelessWidget { | |
static final List<String> strings = [ | |
Span.Year.stringValue, | |
Span.Month.stringValue, | |
Span.Day.stringValue, | |
Span.None.stringValue, | |
]; | |
static final List<String> yearStrings = | |
List<int>.generate(10, (i) => i + 1).map((i) => '$i').toList(); | |
static final List<String> monthStrings = | |
List<int>.generate(12, (i) => i + 1).map((i) => '$i').toList(); | |
static final List<String> dayStrings = | |
List<int>.generate(365, (i) => i + 1).map((i) => '$i').toList(); | |
final Span selectedSpan; | |
final int range; | |
final ValueChanged<String> onSpanChanged; | |
final ValueChanged<int> onRangeChanged; | |
CycleSelectButtons( | |
{@required this.selectedSpan, | |
@required this.onSpanChanged, | |
@required this.onRangeChanged, | |
@required this.range}) | |
: assert(selectedSpan != null), | |
assert(onRangeChanged != null), | |
assert(onSpanChanged != null), | |
assert(range != null); | |
@override | |
Widget build(BuildContext context) { | |
return Row( | |
children: _dropdowns, | |
mainAxisAlignment: MainAxisAlignment.center, | |
); | |
} | |
List<Widget> get _dropdowns { | |
List<Widget> dropdowns = [ | |
AdaptiveDropdown( | |
itemStrings: strings, | |
selectedItemString: selectedSpan.stringValue, | |
onChanged: onSpanChanged, | |
), | |
]; | |
if (selectedSpan == Span.None) { | |
return dropdowns; | |
} else { | |
switch (selectedSpan) { | |
case Span.Year: | |
dropdowns.add( | |
AdaptiveDropdown( | |
itemStrings: yearStrings, | |
selectedItemString: '$range', | |
onChanged: (value) => onRangeChanged(int.parse(value)), | |
), | |
); | |
break; | |
case Span.Month: | |
dropdowns.add( | |
AdaptiveDropdown( | |
itemStrings: monthStrings, | |
selectedItemString: '$range', | |
onChanged: (value) => onRangeChanged(int.parse(value)), | |
), | |
); | |
break; | |
case Span.Day: | |
dropdowns.add( | |
AdaptiveDropdown( | |
itemStrings: dayStrings, | |
selectedItemString: '$range', | |
onChanged: (value) => onRangeChanged(int.parse(value)), | |
), | |
); | |
break; | |
case Span.None: | |
break; | |
} | |
return dropdowns; | |
} | |
} | |
} | |
enum Span { | |
Year, | |
Month, | |
Day, | |
None, | |
} | |
extension SpanExt on Span { | |
static Span initFrom(String spanString) { | |
switch (spanString) { | |
case '年': | |
return Span.Year; | |
break; | |
case '月': | |
return Span.Month; | |
break; | |
case '日': | |
return Span.Day; | |
break; | |
} | |
return Span.None; | |
} | |
String get stringValue { | |
switch (this) { | |
case Span.Year: | |
return '年'; | |
break; | |
case Span.Month: | |
return '月'; | |
break; | |
case Span.Day: | |
return '日'; | |
break; | |
case Span.None: | |
return '未設定'; | |
break; | |
} | |
return "未設定"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment