【问题标题】:All tabs keeps rebuilding when changing from one to another从一个更改到另一个时,所有选项卡都会不断重建
【发布时间】:2020-02-14 02:24:49
【问题描述】:

我遇到了一个问题,我在四个选项卡之间切换,每次单击其中一个,CupertinoTabView 中的所有 4 个小部件都会重建。

我尝试将三进制更改为开关,但结果是一样的。 还尝试在所有 4 个页面上使用 automatickeepaliveclientmixin(使用 super on build 方法和 wantKeepAlive getter),但没有用。

这部分代码如下:


class _MainTabsState extends State<MainTabs> {

  _buildCartButton(index) {
    // Some code I do here
  }

  int index = 0;

  @override
  Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: [
          BottomNavigationBarItem(
            title: Text(I18n.of(context).home, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.home),
          ),
          BottomNavigationBarItem(
            title: Text(I18n.of(context).search, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.search),
          ),
          _buildCartButton(index),
          BottomNavigationBarItem(
            title: Text(I18n.of(context).user, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.person),
          ),
        ],
        activeColor: Colors.orange,
        currentIndex: index,
        onTap: (ind) {
          setState(() {
            index = ind;
          });
        },
      ),
      tabBuilder: (context, i) {
        return CupertinoTabView(builder: (context) {
          return (i == 0)
              ? HomePage()
              : (i == 1) ? SearchPage() : (i == 2) ? CartPage() : UserPage();
        });
      },
    );
  }
}

我只是在每个页面的构建方法开始时打印一些内容,每次更改选项卡时都会看到 4 个打印。

我还使用 Cupertino,因为我需要在页面之间保持底部栏(例如,我在 HomePage 上使用导航器通向另一个屏幕,我需要底部栏显示在那里)。

编辑:这是其中一页的代码。我在每一页都进行打印,每次单击其中一个选项卡时,我都会在终端上看到打印。

class HomePage extends StatefulWidget {
  HomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _HomePageState extends State<HomePage> with AutomaticKeepAliveClientMixin {
  _changeLanguage(CartModel model) {
    if (I18n.of(context).toString() == 'Instance of \'_I18n_en_US\'') {
      I18n.onLocaleChanged(Locale('pt', 'BR'));
      model.changeCurrency('BRL');
    }
    if (I18n.of(context).toString() == 'Instance of \'_I18n_pt_BR\'') {
      I18n.onLocaleChanged(Locale('en', 'US'));
      model.changeCurrency('USD');
    }
  }

  @override
  bool get wantKeepAlive => true;


  @override
  Widget build(BuildContext context) {
    super.build(context);

    print('hi home');
    return Scaffold(
    ...

【问题讨论】:

  • 重建后您面临什么问题。在 Flutter 中,预计 build 方法可以随时被调用。
  • 构建方法应该使用您的状态类的字段来生成没有任何副作用的 UI,并且框架将决定何时调用构建方法。
  • 我也有同样的问题。非常感谢任何解决方案或解决方法。

标签: flutter


【解决方案1】:

我遇到了类似的问题。当我通过给它们一个列表来组织要在 CupertinoTabView 中显示的页面时,这个问题得到了解决。

    class _MainTabsState extends State<MainTabs> {

    _buildCartButton(index) {
    // Some code I do here
    }

    int index = 0;
 
    final List<Widget> _pages = [
    HomePage(),
    SearchPage(),
    CartPage(),
    UserPage()];

    @override
    Widget build(BuildContext context) {
    return CupertinoTabScaffold(
      tabBar: CupertinoTabBar(
        items: [
          BottomNavigationBarItem(
            title: Text(I18n.of(context).home, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.home),
          ),
          BottomNavigationBarItem(
            title: Text(I18n.of(context).search, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.search),
          ),
          _buildCartButton(index),
          BottomNavigationBarItem(
            title: Text(I18n.of(context).user, style: TextStyle(fontSize: 12.0)),
            icon: Icon(Icons.person),
          ),
        ],
        activeColor: Colors.orange,
        currentIndex: index,
        onTap: (ind) {
          setState(() {
            index = ind;
          });
        },
      ),
      tabBuilder: (context, i) {
        return CupertinoTabView(builder: (context) {
          return _pages[i];
        });
      },
    );
  }
}

【讨论】:

    【解决方案2】:

    您需要将AutomaticKeepAliveClientMixin 添加到每个选项卡的小部件。例如:

    class _SearchPageState State extends State<SearchPage> with AutomaticKeepAliveClientMixin{
    

    这将确保您的页面不会在每次用户更改标签时重新构建。

    【讨论】:

    • 呃,我就是这么做的?我在我的问题中写了这个,但它不起作用。
    • 你能分享其中一个类的代码吗,比如SearchPage
    • 你明白了吗..?
    • 作者从未回答我的问题。他在主页上有AutomaticKeepAliveClientMixin,但这不是它需要的地方。因此我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2020-11-22
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 1970-01-01
    相关资源
    最近更新 更多