需求
例如时间,国家地区码选择、日期选择,需要在列表中滑动只选择最中间的选项,单纯的 ListWheelScrollView
与 CupertinoPicker
都无法直接满足样式需求。
效果
组件代码
import 'package:bubble_mobile/util/color_utils.dart';
import 'package:bubble_mobile/util/size_utils.dart';
import 'package:flutter/material.dart';
class ListPick extends StatefulWidget {
final int defaultIndex;
final double itemExtend;
final List<String> itemList;
final ValueChanged<int> onSelectedItemChanged;
final Color backgroundColor;
final Color selectBackgroundColor;
final Color selectFroegroundColor;
final double textSize;
final Color selectTextColor;
final Color unselectTextColor;
final BorderRadiusGeometry borderRadius;
ListPick(
{super.key,
required this.defaultIndex,
required this.itemExtend,
required this.itemList,
required this.onSelectedItemChanged,
this.backgroundColor = ColorUtils.enableBackground,
this.selectBackgroundColor = ColorUtils.mainTheme,
this.selectFroegroundColor = ColorUtils.enableBackground,
this.textSize = SizeUtils.fontBody,
this.selectTextColor = ColorUtils.enableBackground,
this.unselectTextColor = ColorUtils.commonFont,
BorderRadiusGeometry? borderRadius})
: assert(itemList.isNotEmpty),
borderRadius =
borderRadius ?? BorderRadius.circular(SizeUtils.blockWidth * 4);
@override
State<ListPick> createState() => _ListPickState();
}
class _ListPickState extends State<ListPick> {
late int _currentSelectIndex;
@override
void initState() {
super.initState();
_currentSelectIndex = widget.defaultIndex;
widget.onSelectedItemChanged.call(_currentSelectIndex);
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned.fill(
child: Container(
color: widget.backgroundColor,
child: Center(
child: Container(
height: widget.itemExtend,
decoration: BoxDecoration(
borderRadius: widget.borderRadius,
color: widget.selectBackgroundColor,
),
)))),
Positioned.fill(
child: ListWheelScrollView.useDelegate(
controller: FixedExtentScrollController(
initialItem: _currentSelectIndex),
physics: const FixedExtentScrollPhysics(),
squeeze: 1,
itemExtent: widget.itemExtend,
onSelectedItemChanged: (value) {
setState(() {
_currentSelectIndex = value;
});
widget.onSelectedItemChanged.call(value);
},
childDelegate: ListWheelChildBuilderDelegate(
childCount: widget.itemList.length,
builder: ((context, index) {
return Center(
child: Text(widget.itemList[index],
style: TextStyle(
fontSize: widget.textSize,
color: _currentSelectIndex == index
? widget.selectTextColor
: widget.unselectTextColor)),
);
}))))
],
);
}
}
使用
ListPick(
defaultIndex: _selectedCountryIndex ?? 0,
itemExtend: SizeUtils.blockHeight * 6,
onSelectedItemChanged: (value) => _selectedCountryIndex = value,
itemList: _countryList!
.map((e) => "+${e.phoneCode} | ${e.localName}")
.toList(),
))
标签:widget,currentSelectIndex,borderRadius,Flutter,onSelectedItemChanged,列表,itemList
From: https://www.cnblogs.com/seliote/p/16777919.html