如何根据索引更改选项卡的装饰?

How to change decoration of a Tab based on its index?

我正在尝试将我的选项卡设计为以下设计:

我已经能够像那样设计它,但我的问题是如何根据它的索引更改所选选项卡容器的装饰。 如上图,选择了Nike logo标签。
默认情况下,我只能更改所选选项卡中图标的颜色。
所以我想到了检查索引,这样我就可以根据标签是否被选中来改变容器的装饰。

但是,我做不到。

代码:

class HomePage extends StatefulWidget {
  const HomePage({
    Key key,
    @required this.height,
    @required GlobalKey<ScaffoldState> scaffoldKey,
  })  : _scaffoldKey = scaffoldKey,
        super(key: key);

  final double height;
  final GlobalKey<ScaffoldState> _scaffoldKey;

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

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
 TabController _controller;
  int  _activeTabIndex;

  @override
  void initState() {
    super.initState();

    _controller = TabController(vsync: this, length: 6);
    _controller.addListener(_setActiveTabIndex);

  }

  void _setActiveTabIndex() {
  _activeTabIndex = _controller.index;
}

  @override
  Widget build(BuildContext context) {
    final double height = MediaQuery.of(context).size.height;
    final double width = MediaQuery.of(context).size.width;
    return Container(
      height: widget.height,
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
             

 DefaultTabController(
              length: 3,
              child: Padding(
                padding: const EdgeInsets.only(left: 8.0, top: 15),
                child: Text(
                  'Brands',
                  style: TextStyle(
                      fontFamily: 'OpenSansLight',
                      fontSize: 30,
                      fontWeight: FontWeight.w400),
                ),
              ),
            ),
            new TabBar(
                controller: _controller,
                isScrollable: true,
                indicatorWeight: 0.01,
                unselectedLabelColor:
                    Theme.of(context).textTheme.headline1.color,
                unselectedLabelStyle: TextStyle(
                    color: Colors.black,
                    fontSize: 20,
                    fontFamily: 'OpenSansLight'),
                labelStyle: TextStyle(
                    color: Colors.deepPurple,
                    fontSize: 20,
                    fontWeight: FontWeight.w600,
                    fontFamily: 'OpenSansLight'),
                labelColor: Colors.deepPurple,
                tabs: <Widget>[
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
                  Tab(
                      child: Container(
                    height: 50,
                    width: 60,
                    child: Center(
                      child: Icon(ShoeCategory.sneakers),
                    ),
                    decoration: BoxDecoration(
                        color: Colors.white,
                        boxShadow: <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ],
                        borderRadius: BorderRadius.circular(20)),
                  )),
              
                
               
                ]),
            Container(
                height: 250,
                width: width,
                child: TabBarView(controller: _controller, children: [
                 //TAB1
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 //TAB 2
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 //TAB3
                  Container(
                      child: ListView.builder(
                          scrollDirection: Axis.horizontal,
                          itemCount: 8,
                          shrinkWrap: false,
                          itemBuilder: (BuildContext context, int index) {
                            if (index == 7) {
                              return ViewMore(navigationRoute: ChooseKid());
                            }
                            return Padding(
                              padding: const EdgeInsets.all(8.0),
                              child: FeaturedCard(
                                  color1: Colors.lightBlue,
                                  color2: Colors.lightBlue[100],
                                  url:
                                      'https://i.dlpng.com/static/png/6838599_preview.png',
                                  index: random.nextInt(1000000)),
                            );
                          })),
                 
                ]))

          ]))}

}

我猜您只是想实现的是选定的选项卡装饰? 在这种情况下,您可以使用 Tab Controller 并使用索引 属性 来获取当前选定的选项卡。然后您可以检查索引以更改 color/any 其他 属性.

colors: _tabController.index==1?Colors.amber:Colors.white;

在您的标签页 属性 的子项中

这是一个基于您提供的代码的完整示例。我只是添加了一个 var _selectedIndex ,我将其设置为当前显示的选项卡的索引。每次更改选项卡时,它都会调用 setState 来更新 _selectedIndex 的值并刷新 UI,因此所选元素将具有不同的颜色和高度。

代码

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(home: HomePage());
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> with TickerProviderStateMixin {
  TabController _controller;

  int _selectedIndex = 0;

  @override
  void initState() {
    super.initState();
    _controller =
        TabController(vsync: this, length: 5, initialIndex: _selectedIndex);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("asos", style: TextStyle(color: Colors.black)),
        elevation: 0,
        backgroundColor: Colors.white,
        bottom: TabBar(
          controller: _controller,
          isScrollable: true,
          indicatorWeight: 0.01,
          unselectedLabelColor: Theme.of(context).textTheme.headline1.color,
          labelColor: Colors.white,
          onTap: (index) => setState(() => _selectedIndex = index),
          tabs: List<Widget>.generate(
            _controller.length,
            (index) => Tab(
              child: Container(
                width: 60,
                alignment: Alignment.center,
                child: Icon(Icons.beach_access),
                decoration: BoxDecoration(
                  color: index == _selectedIndex ? Colors.orange : Colors.white,
                  boxShadow: index == _selectedIndex
                      ? <BoxShadow>[
                          BoxShadow(
                              color: Theme.of(context).dividerColor,
                              offset: Offset(1, 1),
                              blurRadius: 3,
                              spreadRadius: 2)
                        ]
                      : [],
                  borderRadius: BorderRadius.circular(20),
                ),
              ),
            ),
          ),
        ),
      ),
      body: TabBarView(
        controller: _controller,
        children: List.generate(
          _controller.length,
          (index) => Container(
            alignment: Alignment.center,
            color: Colors.white,
            child: Text(
              "TAB $index",
              style: TextStyle(fontWeight: FontWeight.bold),
            ),
          ),
        ),
      ),
    );
  }
}

截图