Flutter Tab Bar-如何分配每个选定选项卡的不同颜色?

发布于 2025-02-11 17:07:34 字数 1142 浏览 3 评论 0原文

TabBar(
            controller: _tabController,
            unselectedLabelColor: Colors.grey,
            indicator: BoxDecoration(
              borderRadius: BorderRadius.circular(
                16.0,
              ),
              color: colors[_tabController.index],
            ),
            tabs: const [
              Tab(text: "INFO"),
              Tab(text: "ENGAGEMENT"),
              Tab(text: "TRACK"),
            ],
            labelStyle: const TextStyle(
                color: Colors.white,
                fontSize: 13,
                fontWeight: FontWeight.w600),
            unselectedLabelStyle: const TextStyle(
                color: Colors.grey,
                fontSize: 13,
                fontWeight: FontWeight.w600),
          ),
        ),
      ),

我希望每个选项卡在选择时都具有不同的颜色 因此,当索引通过将其存储在列表中时,我试图更改颜色 但是它不用setState就无法正常工作(我知道它不会改变状态,因为快速重新加载后颜色会更改) “在此处输入图像说明”

=“ nofollow noreferrer”> < 。

​输出

TabBar(
            controller: _tabController,
            unselectedLabelColor: Colors.grey,
            indicator: BoxDecoration(
              borderRadius: BorderRadius.circular(
                16.0,
              ),
              color: colors[_tabController.index],
            ),
            tabs: const [
              Tab(text: "INFO"),
              Tab(text: "ENGAGEMENT"),
              Tab(text: "TRACK"),
            ],
            labelStyle: const TextStyle(
                color: Colors.white,
                fontSize: 13,
                fontWeight: FontWeight.w600),
            unselectedLabelStyle: const TextStyle(
                color: Colors.grey,
                fontSize: 13,
                fontWeight: FontWeight.w600),
          ),
        ),
      ),

I wanted Each Tab to have a Different color when they're selected
So I tried to change the color when the index changes by storing them in a list
But it doesnt work without setState (I know its not changing the state because the color changes after quick reload)enter image description here

enter image description here

enter image description here

This is the expected output

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

三寸金莲 2025-02-18 17:07:34

您可以在TabController上包含一个侦听器,并在此处调用setState

  _tabController = TabController(vsync: this, length: myTabs.length)
      ..addListener(() {
        setState(() {});
      });

You can include a listener on TabController and call setState there.

  _tabController = TabController(vsync: this, length: myTabs.length)
      ..addListener(() {
        setState(() {});
      });
可是我不能没有你 2025-02-18 17:07:34

下面的代码应该解决问题。方法的缺失部分是setstate使用当前选择的选项卡索引刷新屏幕。查看屏幕录制和

=“ https://dartpad.dev/?id=d45cffbf73ae3E6713CF36CC2C82248D” rel =“ nofollow noreforler” noreflow noreferrer“ /PI.flutter.dev/flutter/material/tabbar-class.html“ rel =“ nofollow noreferrer”> tabbar 几乎已经完成了所有工作。只有外部圆形边框才能进行自定义,这只是将tabar包装到容器容器非常易于使用,并且高度可定制。

这是代码本身作为 minimal-reproducible-example

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

const colors = [
  Color(0xFF64c636),
  Color(0xFFf2c32c),
  Color(0xFF00a9ce),
];

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late TabController tabController;
  int _tabIndex = 0;
  @override
  void initState() {
    super.initState();
    tabController = TabController(length: 3, vsync: this)
      ..addListener(() {
        setState(() => _tabIndex = tabController.index);
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: 48,
        margin: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          borderRadius: const BorderRadius.all(Radius.circular(20)),
          border: Border.all(width: 2),
        ),
        child: TabBar(
          indicatorWeight: 0,
          controller: tabController,
          indicator: BoxDecoration(
              borderRadius: BorderRadius.circular(
                16.0,
              ),
              color: colors[_tabIndex],
            ),
          labelStyle: const TextStyle(
              color: Colors.white,
              fontSize: 13,
              fontWeight: FontWeight.w600),
          unselectedLabelColor: Colors.grey,
          splashBorderRadius: BorderRadius.circular(20),
          padding: EdgeInsets.all(3),
          tabs: const [
            Tab(text: 'INFO'),
            Tab(text: 'ENGAGEMENT'),
            Tab(text: 'TRACK'),
          ],
        ),
      ),
    );
  }
}

The code below should do the trick. The missing part of your approach is a setState to refresh the screen with the current selected tab index. Check out the screen recording and the live demo on DartPad:

The TabBar do almost all the job already. Only the outside round border should be customized and it's just a matter of wrapping the TabBar into a Container. Containers are pretty easy to work with and highly customizable.

enter image description here

And here's the code itself as a minimal-reproducible-example:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

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

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

const colors = [
  Color(0xFF64c636),
  Color(0xFFf2c32c),
  Color(0xFF00a9ce),
];

class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
  late TabController tabController;
  int _tabIndex = 0;
  @override
  void initState() {
    super.initState();
    tabController = TabController(length: 3, vsync: this)
      ..addListener(() {
        setState(() => _tabIndex = tabController.index);
      });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: 48,
        margin: const EdgeInsets.all(12),
        decoration: BoxDecoration(
          borderRadius: const BorderRadius.all(Radius.circular(20)),
          border: Border.all(width: 2),
        ),
        child: TabBar(
          indicatorWeight: 0,
          controller: tabController,
          indicator: BoxDecoration(
              borderRadius: BorderRadius.circular(
                16.0,
              ),
              color: colors[_tabIndex],
            ),
          labelStyle: const TextStyle(
              color: Colors.white,
              fontSize: 13,
              fontWeight: FontWeight.w600),
          unselectedLabelColor: Colors.grey,
          splashBorderRadius: BorderRadius.circular(20),
          padding: EdgeInsets.all(3),
          tabs: const [
            Tab(text: 'INFO'),
            Tab(text: 'ENGAGEMENT'),
            Tab(text: 'TRACK'),
          ],
        ),
      ),
    );
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文