简体   繁体   中英

Flutter Tabbar builds/rebuilds the middle tab when switching between first and last tab

I'm using a simple tabbar in my flutter app. I borrowed the code from the flutter website and slightly updated to make sure that I can keep the state of each tab using AutomaticKeepAliveClientMixin . Here is my code:

import 'package:flutter/material.dart';

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

class TabBarDemo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              tabs: [
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: Text('Tabs Demo'),
          ),
          body: TabBarView(
            children: [
              Page1(),
              Page2(),
              Page3(),
            ],
          ),
        ),
      ),
    );
  }
}

class Page1 extends StatefulWidget {
  @override
  _Page1State createState() => _Page1State();
}

class _Page1State extends State<Page1>
    with AutomaticKeepAliveClientMixin<Page1> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p1');
    return Container(
      child: Center(
        child: Icon(Icons.directions_car),
      ),
    );
  }
}

class Page2 extends StatefulWidget {
  @override
  _Page2State createState() => _Page2State();
}

class _Page2State extends State<Page2>
    with AutomaticKeepAliveClientMixin<Page2> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p2');
    return Container(
      child: Center(
        child: Icon(Icons.directions_transit),
      ),
    );
  }
}

class Page3 extends StatefulWidget {
  @override
  _Page3State createState() => _Page3State();
}

class _Page3State extends State<Page3>
    with AutomaticKeepAliveClientMixin<Page3> {
  @override
  bool get wantKeepAlive => true;
  @override
  Widget build(BuildContext context) {
    super.build(context);
    print('p3');
    return Container(
      child: Center(
        child: Icon(Icons.directions_bike),
      ),
    );
  }
}

As you see, I have 3 tabs and each tab simply displays one icon. The problem is that when I switch between first and 3rd tabs (Page1 and Page3), the middle tab keeps rebuilding until I switch to that tab (Page2) and only at that point it doesn't get rebuilt anymore. You can see in the debug console once switching between 1st and 3rd tab (without switching to 2nd tab) that it keeps printing "p2".

How can I stop this behavior? I do not want a tab to get built until it's selected.

You can avoid rebuiding widgets by adding const keyword like this

TabBarView(
 children: [
    const Page1(),
    const Page2(),
    const Page3(),
   ],
),

For future reference, if someone faces this problem, I got a good answer on Github here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM