flutter 自定义抖动选项卡栏

laik7k3q  于 2023-06-24  发布在  Flutter
关注(0)|答案(1)|浏览(137)

如何在Flutter中实现这种设计(单向和往返),同时整合现有的TabBar功能?

44u64gxh

44u64gxh1#

下面是一些代码产生一个非常接近的结果。基本上,它使用CustomPainter在TabBar上绘制所需的样式。我已经想出了所有的几何数字自己,但你可以尝试推导一些干净的公式生产代码。另外,我只为一个状态创建了CustomPainter,但您可以创建两个状态,并根据TabController状态在它们之间切换。

import 'dart:math';

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

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("EXAMPLE"),
      ),
      body: DefaultTabController(
        length: 2,
        child: Center(
          child: Container(
            width: 300,
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(10),
              color: Colors.grey[200],
            ),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Stack(
                  children: [
                    CustomPaint(
                      size: const Size(double.infinity, 50),
                      painter: BorderPainter(),
                    ),
                    const TabBar(
                      labelColor: Colors.blue,
                      unselectedLabelColor: Colors.grey,
                      indicatorColor: Colors.transparent,
                      tabs: [
                        Tab(icon: Text('One Way')),
                        Tab(icon: Text('Round Trip')),
                      ],
                    ),
                  ],
                ),
                const SizedBox(
                  height: 300,
                  child: TabBarView(
                    children: [
                      Icon(CupertinoIcons.arrow_right),
                      Icon(CupertinoIcons.arrow_2_circlepath),
                    ],
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}

class BorderPainter extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    double strokeWidth = 1.5;

    var paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = strokeWidth
      ..strokeCap = StrokeCap.round
      ..style = PaintingStyle.stroke;

    canvas.drawArc(
      const Offset(1, 1) & const Size(20, 20),
      pi,
      pi / 2,
      false,
      paint,
    );
    canvas.drawLine(
      const Offset(10, 1),
      Offset(size.width / 2 - 20, 1),
      paint,
    );
    canvas.drawArc(
      Offset(size.width / 2 - 22, 1) & const Size(5, 5),
      3 * pi / 2,
      pi / 4,
      false,
      paint,
    );
    canvas.drawLine(
      Offset(size.width / 2 - 17, 2.5),
      Offset(size.width / 2 + 20, size.height - 2.5),
      paint,
    );
    canvas.drawArc(
      Offset(size.width / 2 + 20, size.height - 6) & const Size(5, 5),
      pi / 2,
      pi / 4,
      false,
      paint,
    );
    canvas.drawLine(
      Offset(size.width / 2 + 23.5, size.height - 1),
      Offset(size.width - 10, size.height - 1),
      paint,
    );
    canvas.drawArc(
      Offset(size.width - 21, size.height - 1) & const Size(20, 20),
      3 * pi / 2,
      pi / 2,
      false,
      paint,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }
}

相关问题