There was a requirement made some time ago that there was a UI to implement a cool TabBar switch, but the effect that Flutter provided was limited. Finally, I realized it through my own exploration, so I feel it necessary to record it. Also provide a train of thought to the officer friend that needs.

This is what the UI wants (roughly in this direction, not only that simple, but also some fancy effects)

But this is what I did when I masturbated

So I can only model change the official UnderlineTabIndicator, detailed operation to see how I copy homework ~

Copying homework:

1. To find the answer

TabBar() has a property called Indicator that supports custom indicators

2. Copy

  • Create a file and name itrectangle_indicator.dart(Name optional)
  • Point into theUnderlineTabIndicator, Copy
  • Paste content intorectangle_indicator.dart
  • Then change the associated class name toRectangleIndicator
  • Handle the error message if the class name does not correspond

3. Change

Modify as requiredIndicator (Location, size)Paint (Styles)Can be

To be more flexible, you can expose some configurations, such as:

// final double radius; // Final EdgeInsets padding; // Final Color rectangleColor; // Final Color? shadowColor;Copy the code
Const RectangleIndicator({this. BorderSide = const borderSide (width: 2.0, color: RectangleIndicator) Color. White), this.padding = const EdgeInsets. Zero, this.radius = 4.0, this.padding = const EdgeInsets. this.rectangleColor = Colors.redAccent, this.shadowColor, }) : assert(borderSide ! = null), assert(insets ! = null);Copy the code
// Draw indicator void paint(Canvas Canvas, Offset Offset, ImageConfiguration Configuration) {assert(Configuration! = null); assert(configuration.size ! = null); final Rect rect = offset & configuration.size! ; final TextDirection textDirection = configuration.textDirection! ; Final Rect indicator = decoration._indicatorRectFor(rect, TextDirection). Deflate (decoration. BorderSide. Width / 2.0); Final RRect RRect = Rrect.fromRectAndRadius (Indicator, radius.circular (decoration.radius)); final Paint paint = decoration.borderSide.toPaint() .. style = PaintingStyle.fill .. color = decoration.rectangleColor; final Path path = Path().. addRRect(rrect.shift(Offset(1, 1))); // Draw shadows if (ideograph. ShadowColor! = null) { canvas.. drawShadow(path, decoration.shadowColor! , 4, false); } // Draw the rounded rectangle canvas.. drawRRect(rrect, paint); }Copy the code
// Calculate indicator rect rect _indicatorRectFor(rect rect, TextDirection TextDirection) {assert(rect! = null); assert(textDirection ! = null); final Rect indicator = insets.resolve(textDirection).deflateRect(rect); return Rect.fromLTWH( indicator.left + padding.left, padding.top, indicator.width - padding.left - padding.right, indicator.height - padding.top - padding.bottom, ); }Copy the code

So much for the rectangle_indicator. Dart changes

It’s also easy to use

3. * * * * you hand it in

Demo

This article is intended as a daily development document, so it only provides a simple direction and thought. Different needs should also have different effects, and finally need to be carved carefully.