aves/lib/widgets/common/basic/wheel.dart
Thibault Deckers 44ed934a8c added time-to-take-action 3s option;
use stretch over bouncing overscroll;
fixed time shift wheel scroll bar
2022-05-23 12:34:41 +09:00

94 lines
2.8 KiB
Dart

import 'package:flutter/material.dart';
class WheelSelector<T> extends StatefulWidget {
final ValueNotifier<T> valueNotifier;
final List<T> values;
final TextStyle textStyle;
final TextAlign textAlign;
const WheelSelector({
super.key,
required this.valueNotifier,
required this.values,
required this.textStyle,
required this.textAlign,
});
@override
State<WheelSelector<T>> createState() => _WheelSelectorState<T>();
}
class _WheelSelectorState<T> extends State<WheelSelector<T>> {
late final ScrollController _controller;
static const itemSize = Size(40, 40);
ValueNotifier<T> get valueNotifier => widget.valueNotifier;
List<T> get values => widget.values;
@override
void initState() {
super.initState();
var indexOf = values.indexOf(valueNotifier.value);
_controller = FixedExtentScrollController(
initialItem: indexOf,
);
}
@override
Widget build(BuildContext context) {
const background = Colors.transparent;
final foreground = DefaultTextStyle.of(context).style.color!;
return NotificationListener<ScrollNotification>(
// cancel notification bubbling so that the dialog scroll bar
// does not misinterpret wheel scrolling for dialog content scrolling
onNotification: (notification) => true,
child: Padding(
padding: const EdgeInsets.all(8),
child: SizedBox(
width: itemSize.width,
height: itemSize.height * 3,
child: ShaderMask(
shaderCallback: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
background,
foreground,
foreground,
background,
],
).createShader,
child: Theme(
data: Theme.of(context).copyWith(
scrollbarTheme: ScrollbarThemeData(
thumbVisibility: MaterialStateProperty.all(false),
),
),
child: ListWheelScrollView(
controller: _controller,
physics: const FixedExtentScrollPhysics(parent: BouncingScrollPhysics()),
diameterRatio: 1.2,
itemExtent: itemSize.height,
squeeze: 1.3,
onSelectedItemChanged: (i) => valueNotifier.value = values[i],
children: values
.map((i) => SizedBox.fromSize(
size: itemSize,
child: Text(
'$i',
textAlign: widget.textAlign,
style: widget.textStyle,
),
))
.toList(),
),
),
),
),
),
);
}
}