참고 : github.com/levent-kantaroglu/horizontal_picker
위의 분 number picker를 토대로 custom 했다.
ListWhellScrollView 안 숫자 데이터를 세로 선으로 변경
Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Container(
height: widget.curItem["height"],
width: 1,
color: Colors.black,
),
),
],
)
10마디 마다 길이 다르게 해주기
class _HorizantalPickerState extends State<HorizantalPicker> {
...
List<Map> valueMap = [];
@override
void initState() {
super.initState();
for (var i = 0; i <= widget.divisions; i++) {
int _height = 24;
if(i % 10 == 0) {
_height = 34;
}
valueMap.add({
"value": widget.minValue +
((widget.maxValue - widget.minValue) / widget.divisions) * i,
"fontSize": 14.0,
"color": widget.passiveItemsTextColor,
"height" : _height,
});
}
...
}
...
Widget build(BuildContext context) {
return Container(
...
child: Scaffold(
...
body: Stack(
children: <Widget>[
RotatedBox(
quarterTurns: 3,
child: ListWheelScrollView(
controller: _scrollController,
itemExtent: 10,
onSelectedItemChanged: (item) {
setState(() {
int decimalCount = 1;
num fac = pow(10, decimalCount);
valueMap[item]["value"] =
(valueMap[item]["value"] * fac).round() / fac;
widget.onChanged(valueMap[item]["value"]);
for (var i = 0; i < valueMap.length; i++) {
int _height = 24;
if(i % 10 == 0) {
_height = 34;
}
if (i == item) {
valueMap[item]["color"] = widget.activeItemTextColor;
valueMap[item]["fontSize"] = 15.0;
valueMap[item]["hasBorders"] = true;
valueMap[item]["height"] = _height;
} else {
valueMap[i]["color"] = widget.passiveItemsTextColor;
valueMap[i]["fontSize"] = 14.0;
valueMap[i]["hasBorders"] = false;
valueMap[i]["height"] = _height;
}
}
});
...
)
...
)
...
]
...
)
...
)
...
)
...
)
}
}
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_app/utils/horizontal_picker.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: 'Horizontal Picker',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.grey,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _maxValue = 250;
int _divisions = 250;
double? newValue;
@override
void initState() {
newValue = (_maxValue ~/ 2) as double;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(newValue.toString()),
Container(
margin: EdgeInsets.all(10),
height: 120,
child: HorizantalPicker(
minValue: 0,
maxValue: _maxValue,
divisions: _divisions,
onChanged: (value) {
setState(() {
newValue = value;
});
},
),
),
],
),
);
}
}
결과
최종코드
import 'dart:math';
import 'package:flutter/material.dart';
enum InitialPosition { start, center, end }
class HorizantalPicker extends StatefulWidget {
final double minValue, maxValue;
final int divisions;
final Function(double) onChanged;
final InitialPosition initialPosition;
final Color backgroundColor;
final bool showCursor;
final Color cursorColor;
final Color activeItemTextColor;
final Color passiveItemsTextColor;
final String? suffix;
HorizantalPicker(
{required this.minValue,
required this.maxValue,
required this.divisions,
required this.onChanged,
this.initialPosition = InitialPosition.center,
this.backgroundColor = Colors.white,
this.showCursor = true,
this.cursorColor = Colors.red,
this.activeItemTextColor = Colors.blue,
this.passiveItemsTextColor = Colors.grey,
this.suffix = ''})
: assert(minValue < maxValue),
assert(onChanged != null);
@override
_HorizantalPickerState createState() => _HorizantalPickerState();
}
class _HorizantalPickerState extends State<HorizantalPicker> {
List<double> valueList = [];
late FixedExtentScrollController _scrollController;
int selectedFontSize = 14;
List<Map> valueMap = [];
@override
void initState() {
super.initState();
for (var i = 0; i <= widget.divisions; i++) {
int _height = 24;
if(i % 10 == 0) {
_height = 34;
}
valueMap.add({
"value": widget.minValue +
((widget.maxValue - widget.minValue) / widget.divisions) * i,
"fontSize": 14.0,
"color": widget.passiveItemsTextColor,
"height" : _height,
});
}
setScrollController();
}
setScrollController() {
int initialItem;
switch (widget.initialPosition) {
case InitialPosition.start:
initialItem = 0;
break;
case InitialPosition.center:
initialItem = (valueMap.length ~/ 2);
break;
case InitialPosition.end:
initialItem = valueMap.length - 1;
break;
}
_scrollController = FixedExtentScrollController(initialItem: initialItem);
}
@override
Widget build(BuildContext context) {
// _scrollController.jumpToItem(curItem);
return Container(
padding: EdgeInsets.all(3),
margin: EdgeInsets.all(20),
height: 150,
alignment: Alignment.center,
child: Scaffold(
backgroundColor: widget.backgroundColor,
body: Stack(
children: <Widget>[
RotatedBox(
quarterTurns: 3,
child: ListWheelScrollView(
controller: _scrollController,
itemExtent: 10,
onSelectedItemChanged: (item) {
setState(() {
int decimalCount = 1;
num fac = pow(10, decimalCount);
valueMap[item]["value"] =
(valueMap[item]["value"] * fac).round() / fac;
widget.onChanged(valueMap[item]["value"]);
for (var i = 0; i < valueMap.length; i++) {
int _height = 24;
if(i % 10 == 0) {
_height = 34;
}
if (i == item) {
valueMap[item]["color"] = widget.activeItemTextColor;
valueMap[item]["fontSize"] = 15.0;
valueMap[item]["hasBorders"] = true;
valueMap[item]["height"] = _height;
} else {
valueMap[i]["color"] = widget.passiveItemsTextColor;
valueMap[i]["fontSize"] = 14.0;
valueMap[i]["hasBorders"] = false;
valueMap[i]["height"] = _height;
}
}
});
setState(() {});
},
children: valueMap.map((Map curValue) {
//print("q");
//print(widget.backgroundColor.toString());
return ItemWidget(curValue,
backgroundColor: widget.backgroundColor,
suffix: widget.suffix!);
}).toList()),
),
Visibility(
visible: widget.showCursor,
child: Container(
alignment: Alignment.center,
padding: EdgeInsets.all(5),
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
color: widget.cursorColor.withOpacity(0.3)),
width: 3,
),
),
)
],
),
),
);
}
}
class ItemWidget extends StatefulWidget {
final Map curItem;
final Color backgroundColor;
final String? suffix;
ItemWidget(this.curItem, {required this.backgroundColor, this.suffix});
@override
_ItemWidgetState createState() => _ItemWidgetState();
}
class _ItemWidgetState extends State<ItemWidget> {
@override
void initState() {
super.initState();
int decimalCount = 1;
num fac = pow(10, decimalCount);
}
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 2),
decoration: BoxDecoration(
color: widget.backgroundColor,
borderRadius: BorderRadius.circular(10),
),
child: RotatedBox(
quarterTurns: 1,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: EdgeInsets.symmetric(vertical: 10.0),
child: Container(
height: widget.curItem["height"],
width: 1,
color: Colors.black,
),
),
],
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_app/utils/horizontal_picker.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: 'Horizontal Picker',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.grey,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
double _maxValue = 250;
int _divisions = 250;
double? newValue;
@override
void initState() {
newValue = (_maxValue ~/ 2) as double;
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(newValue.toString()),
Container(
margin: EdgeInsets.all(10),
height: 120,
child: HorizantalPicker(
minValue: 0,
maxValue: _maxValue,
divisions: _divisions,
onChanged: (value) {
setState(() {
newValue = value;
});
},
),
),
],
),
);
}
}
320x100
'프로그래밍 > Flutter-Dart' 카테고리의 다른 글
[Flutter] Login App (2) (0) | 2021.03.24 |
---|---|
[Flutter] Vlc Player & Circular Percent Indicator (0) | 2021.03.24 |
[Flutter] Horizontal Number Picker (0) | 2021.03.23 |
[Flutter] DatePicker (iOS style) (0) | 2021.03.23 |
[Flutter] Image Picker (2) | 2021.03.23 |
댓글