scroll_picker.dart
3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright (c) 2018, codegrue. All rights reserved. Use of this source code
// is governed by the MIT license that can be found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
/// This helper widget manages the scrollable content inside a picker widget.
class ScrollPicker extends StatefulWidget {
ScrollPicker({
Key key,
@required this.items,
@required this.initialValue,
@required this.onChanged,
}) : assert(items != null),
super(key: key);
// Events
final ValueChanged<String> onChanged;
// Variables
final List<String> items;
final String initialValue;
@override
_ScrollPickerState createState() => _ScrollPickerState(initialValue);
}
class _ScrollPickerState extends State<ScrollPicker> {
_ScrollPickerState(this.selectedValue);
// Constants
static const double itemHeight = 50.0;
// Variables
double widgetHeight;
int numberOfVisibleItems;
int numberOfPaddingRows;
double visibleItemsHeight;
double offset;
String selectedValue;
ScrollController scrollController;
@override
void initState() {
super.initState();
int initialItem = widget.items.indexOf(selectedValue);
scrollController = FixedExtentScrollController(initialItem: initialItem);
}
@override
Widget build(BuildContext context) {
final ThemeData themeData = Theme.of(context);
TextStyle defaultStyle = themeData.textTheme.bodyText2;
TextStyle selectedStyle =
themeData.textTheme.headline5.copyWith(color: themeData.accentColor);
return LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
widgetHeight = constraints.maxHeight;
return Stack(
children: <Widget>[
GestureDetector(
onTapUp: _itemTapped,
child: ListWheelScrollView.useDelegate(
childDelegate: ListWheelChildBuilderDelegate(
builder: (BuildContext context, int index) {
if (index < 0 || index > widget.items.length - 1) {
return null;
}
var value = widget.items[index];
final TextStyle itemStyle =
(value == selectedValue) ? selectedStyle : defaultStyle;
return Center(
child: Text(value, style: itemStyle),
);
}),
controller: scrollController,
itemExtent: itemHeight,
onSelectedItemChanged: _onSelectedItemChanged,
physics: FixedExtentScrollPhysics(),
),
),
Center(child: Divider()),
Center(
child: Container(
height: itemHeight,
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: themeData.accentColor, width: 1.0),
bottom:
BorderSide(color: themeData.accentColor, width: 1.0),
),
),
),
)
],
);
},
);
}
void _itemTapped(TapUpDetails details) {
Offset position = details.localPosition;
double center = widgetHeight / 2;
double changeBy = position.dy - center;
double newPosition = scrollController.offset + changeBy;
// animate to and center on the selected item
scrollController.animateTo(newPosition,
duration: Duration(milliseconds: 500), curve: Curves.easeInOut);
}
void _onSelectedItemChanged(int index) {
String newValue = widget.items[index];
if (newValue != selectedValue) {
selectedValue = newValue;
widget.onChanged(newValue);
}
}
}