Skip to content

Instantly share code, notes, and snippets.

@tanabe1478
Created February 27, 2021 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanabe1478/51dc6269df12010b828467edbbbc5274 to your computer and use it in GitHub Desktop.
Save tanabe1478/51dc6269df12010b828467edbbbc5274 to your computer and use it in GitHub Desktop.
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