“This is the 12th day of my participation in the August More Text Challenge. For details, see: August More Text Challenge juejin.cn/post/698796…
I just learned how to use the TabBar, and the use of the indicator is less. Try a custom label indicator today;
TabBar provides the Indicator attribute. Users are allowed to customize indicators, but custom indicators will invalidate indicatorColor/indicatorWeight/indicatorPadding. The default indicator is UnderlineTabIndicator;
Decoration get _indicator { if (widget.indicator ! = null) return widget.indicator; final TabBarTheme tabBarTheme = TabBarTheme.of(context); if (tabBarTheme.indicator ! = null) return tabBarTheme.indicator; Color color = widget.indicatorColor ?? Theme.of(context).indicatorColor; if (color.value == Material.of(context).color? .value) color = Colors.white; return UnderlineTabIndicator( insets: widget.indicatorPadding, borderSide: BorderSide(width: widget.indicatorWeight, color: color)); }Copy the code
Source code analysis
class ACETabBarIndicator extends Decoration {
@override
BoxPainter createBoxPainter([onChanged]) => _ACETabBarIndicatorPainter(this, onChanged);
}
class _ACETabBarIndicatorPainter extends BoxPainter {
final ACETabBarIndicator decoration;
_ACETabBarIndicatorPainter(this.decoration, VoidCallback onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
// TODO: implement paint
}
}
Copy the code
According to the source code analysis, all customized indicators should be inherited from Decoration; When drawing BoxPainter, you can obtain the corresponding Tab size and position by Offset and ImageConfiguration.
Case try
The custom ACETabBarIndicator is isolated in the side dish. There is no custom TabBar. Therefore, the properties in the TabBar cannot be used directly. If you want to use the ACETabBarIndicator directly in the TabBar, you can try to customize it by placing the ACETabBarIndicator in the TabBar source.
The customization is mainly to implement the various styles of paint process, the side dish is simple to try the following several indicator styles;
1. ACETabBarIndicatorType. Circle – > solid dot
To set height to diameter, draw a circle in the middle of the bottom of the Tab. Note that the starting position is the center of the bottom, minus the radius;
canvas.drawCircle(
Offset(offset.dx + (configuration.size.width) / 2, configuration.size.height - _height),
_height, _paint);
Copy the code
2. ACETabBarIndicatorType. Triangle – > upper triangular
The side dish generates an upper triangle by drawing Path; Which needs to be compatible with a triangle height upper limit;
if (_height > configuration.size.height) _height = _kIndicatorHeight; Path _path = Path() .. moveTo(offset.dx + (configuration.size.width) / 2 - _height, configuration.size.height) .. lineTo(_height * tan(pi / 6) + offset.dx + (configuration.size.width - _height) / 2, configuration.size.height - _height) .. lineTo(_height * tan(pi / 6) + offset.dx + (configuration.size.width + _height) / 2, configuration.size.height); canvas.drawPath(_path, _paint);Copy the code
3. ACETabBarIndicatorType. Rrect – > rounded rectangle (the entire Tab)
Draw a rounded rectangle with an Offset position and a Tab size of ImageConfiguration;
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(offset.dx, offset.dy, configuration.size.width, configuration.size.height),
Radius.circular(_kIndicatorAngle)),
_paint);
Copy the code
4. ACETabBarIndicatorType. Rrect_inner – > rounded rectangle (padding)
< span style = “font-size: 15px; color: RGB (50, 50, 50);” The start height of the rectangle needs to be reduced by 1, because Paint defaults to a line width of 1.
canvas.drawRRect(
RRect.fromRectAndRadius(
Rect.fromLTWH(
offset.dx + height, height - 1,
configuration.size.width - height * 2,
configuration.size.height - height * 2 - 2),
Radius.circular(_kIndicatorAngle)),
_paint);
Copy the code
5. ACETabBarIndicatorType. Runderline – > rounded corners underscore
The default TabBar indicator style is UnderlineTabIndicator; Just change the Paint line style to round.
canvas.drawLine( Offset(offset.dx, configuration.size.height - height / 2), Offset(offset.dx + configuration.size.width, configuration.size.height - height / 2), _paint.. strokeWidth = height / 2);Copy the code
6. ACETabBarIndicatorType. Runderline_fixed – > fixed-length rounded corners underscore
< span style = “box-sizing: border-box; color: RGB (74, 74, 74); line-height: 20px; font-size: 15px! Important; word-break: block;”
if (_width > configuration.size.width) _width = configuration.size.width / 3; canvas.drawLine( Offset(offset.dx + (configuration.size.width - _width) / 2, configuration.size.height - height / 2), Offset(offset.dx + (configuration.size.width + _width) / 2, configuration.size.height - height / 2), _paint.. strokeWidth = height / 2);Copy the code
ACETabBarIndicator case source code
The adaptation test of the customized label indicator is not complete, if there are mistakes, please guide!
Source: Young Monk Atze