MyTabPageSelector(
controller: _controller,
color: Color(0x21000000),
//borderColor: Colors.blue you can set your own color if you want
selectedColor: Colors.white,
)
class TabPageSelectorIndicator extends StatelessWidget {
/// Creates an indicator used by [TabPageSelector].
///
/// The [backgroundColor], [borderColor], and [size] parameters must not be null.
const TabPageSelectorIndicator({
Key key,
@required this.backgroundColor,
@required this.size,
}) : assert(backgroundColor != null),
assert(size != null),
super(key: key);
/// The indicator circle's background color.
final Color backgroundColor;
/// The indicator circle's diameter.
final double size;
@override
Widget build(BuildContext context) {
return Container(
width: size,
height: size,
margin: const EdgeInsets.all(4.0),
decoration: BoxDecoration(
color: backgroundColor,
shape: BoxShape.circle,
),
);
}
}
/// Displays a row of small circular indicators, one per tab. The selected
/// tab's indicator is highlighted. Often used in conjunction with a [TabBarView].
///
/// If a [TabController] is not provided, then there must be a [DefaultTabController]
/// ancestor.
class TabPageSelector extends StatelessWidget {
/// Creates a compact widget that indicates which tab has been selected.
const TabPageSelector({
Key key,
this.controller,
this.indicatorSize = 12.0,
this.color,
this.selectedColor,
}) : assert(indicatorSize != null && indicatorSize > 0.0),
super(key: key);
/// This widget's selection and animation state.
///
/// If [TabController] is not provided, then the value of [DefaultTabController.of]
/// will be used.
final TabController controller;
/// The indicator circle's diameter (the default value is 12.0).
final double indicatorSize;
/// The indicator circle's fill color for unselected pages.
///
/// If this parameter is null then the indicator is filled with [Colors.transparent].
final Color color;
/// The indicator circle's fill color for selected pages and border color
/// for all indicator circles.
///
/// If this parameter is null then the indicator is filled with the theme's
/// accent color, [ThemeData.accentColor].
final Color selectedColor;
Widget _buildTabIndicator(
int tabIndex,
TabController tabController,
ColorTween selectedColorTween,
ColorTween previousColorTween,
) {
Color background;
if (tabController.indexIsChanging) {
// The selection's animation is animating from previousValue to value.
final double t = 1.0 - _indexChangeProgress(tabController);
if (tabController.index == tabIndex)
background = selectedColorTween.lerp(t);
else if (tabController.previousIndex == tabIndex)
background = previousColorTween.lerp(t);
else
background = selectedColorTween.begin;
} else {
// The selection's offset reflects how far the TabBarView has / been dragged
// to the previous page (-1.0 to 0.0) or the next page (0.0 to 1.0).
final double offset = tabController.offset;
if (tabController.index == tabIndex) {
background = selectedColorTween.lerp(1.0 - offset.abs());
} else if (tabController.index == tabIndex - 1 && offset > 0.0) {
background = selectedColorTween.lerp(offset);
} else if (tabController.index == tabIndex + 1 && offset < 0.0) {
background = selectedColorTween.lerp(-offset);
} else {
background = selectedColorTween.begin;
}
}
return TabPageSelectorIndicator(
backgroundColor: background,
size: indicatorSize,
);
}
@override
Widget build(BuildContext context) {
final Color fixColor = color ?? Colors.transparent;
final Color fixSelectedColor = selectedColor ?? Theme.of(context).accentColor;
final ColorTween selectedColorTween = ColorTween(begin: fixColor, end: fixSelectedColor);
final ColorTween previousColorTween = ColorTween(begin: fixSelectedColor, end: fixColor);
final TabController tabController = controller ?? DefaultTabController.of(context);
assert(() {
if (tabController == null) {
throw FlutterError(
'No TabController for $runtimeType.\n'
'When creating a $runtimeType, you must either provide an explicit TabController '
'using the "controller" property, or you must ensure that there is a '
'DefaultTabController above the $runtimeType.\n'
'In this case, there was neither an explicit controller nor a default controller.'
);
}
return true;
}());
final Animation<double> animation = CurvedAnimation(
parent: tabController.animation,
curve: Curves.fastOutSlowIn,
);
return AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget child) {
return Semantics(
label: 'Page ${tabController.index + 1} of ${tabController.length}',
child: Row(
mainAxisSize: MainAxisSize.min,
children: List<Widget>.generate(tabController.length, (int tabIndex) {
return _buildTabIndicator(tabIndex, tabController, selectedColorTween, previousColorTween);
}).toList(),
),
);
}
);
}
}
3条答案
按热度按时间cpjpxq1n1#
TabPageSelector
widget不支持它,但您可以创建自己的Widget,我为您创建了一个,检查代码并将文件添加到您的项目中:https://gist.github.com/diegoveloper/9de80d0e22cac8a2ef4357a620b375a9
用法:
mklgxw1f2#
我已经明白你想要什么;要做到这一点,实际上ctrl并点击TabPageSelector,然后去底部搜索TabPageSelectorIndicator(它在底部),然后用下面的内容替换它:
snvhrwxg3#
只需设置边框样式