【问题标题】:Flutter: How to show the first TabBar/TabBarView when returning to page?Flutter:返回页面时如何显示第一个TabBar / TabBarView?
【发布时间】:2021-01-19 10:55:19
【问题描述】:

请查看此Demo app。它有一个 Cupertino 底部导航栏和产品页面上的两个选项卡。我在下面提供了代码 sn-ps(注意:代码主要改编自官方文档)。

我的问题
当点击任何 BottomNavigationBarItem 项目(无论是产品、搜索还是购物车)时,我希望将产品页面上的选项卡控制器的索引重置为 0,并在该页面上调用 setState。我如何做到这一点?

我正在努力实现的目标

  1. 在“产品”页面上,如果我选择右侧选项卡(选项卡索引 = 1),我还希望能够通过点击底部导航中的产品导航回左侧选项卡(选项卡索引 = 0)。
  2. 在产品页面上,如果我选择右标签(标签索引 = 1),然后导航到不同的页面(搜索页面或购物车页面),然后返回产品页面,我想要左标签(标签index = 0) 默认显示。

希望这是有道理的。谢谢!

(免责声明:我是开发和 Stackoverflow 的新手,所以我希望我的问题措辞正确。我一定会在收到相关反馈时对其进行修改)。

ma​​in.dart

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'products_page.dart';
import 'search_page.dart';
import 'cart_page.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo app',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: HomePage(),
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.home),
            title: Text('Products'),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.search),
            title: Text('Search'),
          ),
          BottomNavigationBarItem(
            icon: Icon(CupertinoIcons.shopping_cart),
            title: Text('Cart'),
          ),
        ],
      ),
      tabBuilder: (context, index) {
        CupertinoTabView returnValue;
        switch (index) {
          case 0:
            returnValue = CupertinoTabView(builder: (context) {
              return CupertinoPageScaffold(
                child: ProductsPage(),
              );
            });
            break;
          case 1:
            returnValue = CupertinoTabView(builder: (context) {
              return CupertinoPageScaffold(
                child: SearchPage(),
              );
            });
            break;
          case 2:
            returnValue = CupertinoTabView(builder: (context) {
              return CupertinoPageScaffold(
                child: CartPage(),
              );
            });
            break;
        }
        return returnValue;
      },
    );
  }
}

products_page.dart

import 'package:flutter/material.dart';

class ProductsPage extends StatefulWidget {

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

class _ProductsPageState extends State<ProductsPage> with SingleTickerProviderStateMixin {
  TabController _tabController;

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: NestedScrollView(
        headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
          return <Widget>[
            SliverAppBar(
              floating: false,
              pinned: true,
              flexibleSpace: FlexibleSpaceBar(
                centerTitle: true,
                title: Text('Products'),
              ),
            ),
            SliverPersistentHeader(
              delegate: _SliverAppBarDelegate(
                TabBar(
                  controller: _tabController,
                  labelColor: Colors.black87,
                  unselectedLabelColor: Colors.grey,
                  tabs: [
                    Tab(text: 'LEFT'),
                    Tab(text: 'RIGHT'),
                  ],
                  // controller:,
                ),
              ),
              pinned: true,
            ),
          ];
        },
        body: TabBarView(
          controller: _tabController,
          children: <Widget>[
            Center(child: Text('This is the left tab', style: TextStyle(fontSize: 30))),
            Center(child: Text('This is the right tab', style: TextStyle(fontSize: 30))),
          ],
        ),
      ),
    );
  }
}

class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
  _SliverAppBarDelegate(this._tabBar);

  final TabBar _tabBar;

  @override
  double get minExtent => _tabBar.preferredSize.height;
  @override
  double get maxExtent => _tabBar.preferredSize.height;

  @override
  Widget build(BuildContext context, double shrinkOffset, bool overlapsContent) {
    return Container(
      color: Colors.white,
      child: _tabBar,
    );
  }

  @override
  bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
    return false;
  }
}

【问题讨论】:

  • 请添加一些代码sn-p以便更清楚
  • 你这样做了吗?
  • 看看这个:dev.to/fluttercorner/…
  • @Andrej 该教程展示了如何使用 tabController 设置选项卡。但它没有为上述场景提供任何解决方案。

标签: flutter flutter-layout


【解决方案1】:

试试这个,总是将 initialIndex 设置为 0:

DefaultTabController(
        initialIndex: 0,

【讨论】:

  • initialIndex 仅适用于页面首次构建时,即在第一次渲染页面时它应该默认使用的选项卡,但不适用于已经构建时(我的场景)。所以不幸的是它不能解决这个问题。
猜你喜欢
  • 2020-04-06
  • 1970-01-01
  • 2018-01-13
  • 2021-09-02
  • 2020-11-08
  • 1970-01-01
  • 2020-05-02
  • 2021-08-29
  • 2018-10-27
相关资源
最近更新 更多