Flutter:持久的底部导航在选项卡更改时重建子页面

时间:2021-04-27 20:09:39

标签: flutter flutter-dependencies

我正在使用 persistent_bottom_nav_bar package 并按照他们的自述文件中的概述实现了它。请参考下面的ma​​in.dart代码。

问题:在 page1 上,我可以导航到包含 ListView 的子页面。在该子页面上时,如果我不弹出该页面而只是直接点击底部导航项来更改页面,则子页面上的 ListView 将继续为我导航到的每个选项卡重建。不知道如何防止这种情况发生??

在我的实际实现中(下面是一个简化的代码),这个子页面是一个有状态的小部件。因此,我尝试使用 AutomaticKeepAliveClientMixin 扩展有状态小部件以不重建页面,但这没有帮助。在我在这里给出的示例中,子页面实际上是一个无状态小部件,问题仍然存在。所以我怀疑它源于包本身,而不是页面是有状态的还是无状态的。

任何人可能对正在发生的事情有任何想法?提前致谢。

ma​​in.dart

import 'package:flutter/material.dart';
import 'package:persistent_bottom_nav_bar/persistent-tab-view.dart';

import 'page1.dart';
import 'page2.dart';
import 'page3.dart';
import 'page4.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      home: HomeScaffold(),
    );
  }
}

class HomeScaffold extends StatefulWidget {

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

class _HomeScaffoldState extends State<HomeScaffold> {
  PersistentTabController _controller;

  @override
  void initState() {
    super.initState();
    _controller = PersistentTabController(initialIndex: 0);
  }

  List<Widget> _buildScreens() {
    return [
      Page1(),
      Page2(),
      Page3(),
      Page4(),
    ];
  }

  List<PersistentBottomNavBarItem> _navBarsItems() {
    return [
      _buildBottomNavBarItem('Page 1', Icons.home),
      _buildBottomNavBarItem('Page 2', Icons.search),
      _buildBottomNavBarItem('Page 3', Icons.message),
      _buildBottomNavBarItem('Page 4', Icons.settings),
    ];
  }

  @override
  Widget build(BuildContext context) {

    return PersistentTabView(
      context,
      controller: _controller,
      screens: _buildScreens(),
      items: _navBarsItems(),
      confineInSafeArea: true,
      backgroundColor: Colors.white,
      handleAndroidBackButtonPress: true, 
      resizeToAvoidBottomInset: true, 
      stateManagement: true, 
      // hideNavigationBar: true, 
      hideNavigationBarWhenKeyboardShows: true, 
      decoration: NavBarDecoration(
        borderRadius: BorderRadius.circular(5.0),
        colorBehindNavBar: Colors.white,
      ),
      popAllScreensOnTapOfSelectedTab: true,
      popActionScreens: PopActionScreensType.all,
      itemAnimationProperties: ItemAnimationProperties( 
        duration: Duration(milliseconds: 200),
        curve: Curves.ease,
      ),
      screenTransitionAnimation: ScreenTransitionAnimation( 
        animateTabTransition: true,
        curve: Curves.ease,
        duration: Duration(milliseconds: 200),
      ),
      navBarStyle: NavBarStyle.style8, 
    );

  }
}

PersistentBottomNavBarItem _buildBottomNavBarItem(String title, IconData icon) {
  return PersistentBottomNavBarItem(
    icon: Icon(icon),
    title: title,
    activeColorPrimary: Colors.indigo,
    inactiveColorPrimary: Colors.grey,
  );
}

page1.dart

import 'page1_sub_page.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

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

class _Page1State extends State<Page1> with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    print('Building Page1');
    super.build(context);

    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Center(child: Text('Page1')),
          SizedBox(height: 40),
          RaisedButton(
            onPressed: () => Navigator.of(context).push(
              CupertinoPageRoute(builder: (BuildContext context) => Page1SubPage()),
            ),
            child: Text('Sub-page'),
          ),
        ],
      ),
    );
  }
}

page1_sub_page.dart

import 'package:flutter/material.dart';

class Page1SubPage extends StatelessWidget {
  // Generate dummy list
  final List dummyList = List.generate(100, (index) {
    return {
      "id": index,
      "title": "This is the tile $index",
    };
  });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: SafeArea(
            child: ListView.builder(
              itemCount: dummyList.length,
              itemBuilder: (context, index) {
                print('Building tile $index');
                return Card(
                  elevation: 6,
                  margin: EdgeInsets.all(10),
                  child: ListTile(
                    leading: CircleAvatar(
                      child: Text(dummyList[index]["id"].toString()),
                      backgroundColor: Colors.purple,
                    ),
                    title: Text(dummyList[index]["title"]),
                  ),
                );
              } ,
            )));
  }
}

0 个答案:

没有答案