多鱼小站-薅羊毛社区,折扣网

标题: 如何创建自定义标签栏颤动 [打印本页]

作者: lacken    时间: 2024-7-29 14:04
标题: 如何创建自定义标签栏颤动
[md]你的代码展示了一个具有自定义下划线指示器的 `TabBar`,以及一个用于构建标签页的 `_buildTab` 函数。你想要创建一个在中间有圆角的 `TabBar`。当前的代码在每个标签页的顶部应用了圆角,但没有实现中间圆角的效果。

要实现中间标签页的圆角效果,你需要使用一个自定义的 `TabBar` 并重写 `paint` 方法来绘制带有圆角的分隔线。不过,这通常比较复杂,因为 `TabBar` 的绘制是由其内部逻辑控制的。

一个简单的方法是使用 `CustomPaint` 小部件和 `CustomPainter` 类来绘制圆角的分隔线和背景。下面是一个示例代码,演示如何实现这个效果:

```dart
import 'package:flutter/material.dart';

class RoundedTabBar extends StatefulWidget {
  final List<Widget> tabs;
  final int selectedIndex;
  final ValueChanged<int> onTap;
  final Color indicatorColor;

  RoundedTabBar({
    required this.tabs,
    required this.selectedIndex,
    required this.onTap,
    this.indicatorColor = Colors.green,
  });

  @override
  _RoundedTabBarState createState() => _RoundedTabBarState();
}

class _RoundedTabBarState extends State<RoundedTabBar> with SingleTickerProviderStateMixin {
  late TabController _tabController;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: widget.tabs.length, vsync: this);
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      painter: _RoundedTabBarPainter(
        tabs: widget.tabs,
        selectedIndex: widget.selectedIndex,
        indicatorColor: widget.indicatorColor,
        controller: _tabController,
      ),
      child: TabBar(
        controller: _tabController,
        isScrollable: false,
        indicatorSize: TabBarIndicatorSize.tab,
        labelColor: Colors.black,
        unselectedLabelColor: Colors.grey,
        tabs: widget.tabs,
      ),
    );
  }
}

class _RoundedTabBarPainter extends CustomPainter {
  final List<Widget> tabs;
  final int selectedIndex;
  final Color indicatorColor;
  final TabController controller;

  _RoundedTabBarPainter({required this.tabs, required this.selectedIndex, required this.indicatorColor, required this.controller});

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = indicatorColor
      ..strokeWidth = 4.0
      ..style = PaintingStyle.stroke;

    final tabRects = <Rect>[];
    for (int i = 0; i < tabs.length; i++) {
      final RenderBox renderBox = tabs as Tab; // Assuming tabs are of type Tab
      final tabOffset = renderBox.localToGlobal(Offset.zero);
      final tabRect = Rect.fromLTWH(tabOffset.dx, tabOffset.dy, renderBox.size.width, renderBox.size.height);
      tabRects.add(tabRect);
    }

    // Draw rounded ends for first and last tab
    final firstTabPath = Path()
      ..moveTo(tabRects[0].center.left, tabRects[0].top)
      ..lineTo(tabRects[0].left, tabRects[0].top)
      ..arcToPoint(Offset(tabRects[0].left, tabRects[0].bottom), radius: Radius.circular(25))
      ..lineTo(tabRects[1].left, tabRects[1].bottom);

    final lastTabPath = Path()
      ..moveTo(tabRects.last.center.right, tabRects.last.top)
      ..lineTo(tabRects.last.right, tabRects.last.top)
      ..arcToPoint(Offset(tabRects.last.right, tabRects.last.bottom), radius: Radius.circular(25))
      ..lineTo(tabRects.last.right, tabRects.last.bottom);

    // Draw straight line in the middle
    final middlePath = Path()
      ..moveTo(tabRects[1].right, tabRects[1].top)
      ..lineTo(tabRects[tabs.length - 2].left, tabRects[tabs.length - 2].top);

    // Draw the paths
    canvas.drawPath(firstTabPath, paint);
    canvas.drawPath(middlePath, paint);
    canvas.drawPath(lastTabPath, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

// Usage example:
// TabBar(
//   controller: _tabController,
//   tabs: [
//     Tab(child: _buildTab('Phone')),
//     Tab(child: _buildTab('Email')),
//   ],
// )
```

请注意,这个示例代码只是一个基础的实现,可能需要根据你的具体需求进行调整。特别是 `CustomPainter` 的实现,你需要根据实际的 `Tab` 尺寸和位置来绘制路径。此外,你可能需要处理 `TabController` 的变化,以确保下划线指示器能够正确更新。

这个示例中的 `RoundedTabBar` 是一个自定义的 `TabBar`,它使用 `CustomPaint` 和 `_RoundedTabBarPainter` 来绘制圆角的下划线指示器。你需要将你的 `TabBar` 替换为这个自定义的 `RoundedTabBar`,并传递相同的 `tabs` 参数。
[/md]




欢迎光临 多鱼小站-薅羊毛社区,折扣网 (https://www.codeblogs.cn/) Powered by Discuz! X3.5