为什么我的页面不刷新底部导航在 Flutter ?

fkvaft9z  于 2023-03-31  发布在  Flutter
关注(0)|答案(3)|浏览(152)

我正在使用Flutter中的底部导航栏。我想在切换标签时刷新每个标签。首先,我试图为所有标签重用一个无状态的小部件。但它正在重新渲染页面。我的代码如下:

class _CreateOrderState extends State<CreateOrder> {
  int _currentTabIndex = 0;

  @override
  Widget build(BuildContext context) {
     final _kTabPages = <Widget>[
       FoodCategory(foodCategory: 'nationalFood'),
       FoodCategory(foodCategory: 'fastFood'),
       FoodCategory(foodCategory: 'dessert'),
       FoodCategory(foodCategory: 'drinks'),
     ];

    final _kBottomNavBarItems = <BottomNavigationBarItem>[
      const BottomNavigationBarItem(
        icon: Icon(Icons.fastfood_outlined),
        label: 'Традиционная',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.alarm),
        label: 'Фаст Фуд',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.food_bank_outlined),
        label: 'Дессерты',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.emoji_food_beverage),
        label: 'Напитки',
      ),
    ];
    assert(_kTabPages.length == _kBottomNavBarItems.length);
    final bottomNavBar = BottomNavigationBar(
      items: _kBottomNavBarItems,
      currentIndex: _currentTabIndex,
      type: BottomNavigationBarType.fixed,
      onTap: (int index) {
        setState(() => _currentTabIndex = index);
      },
    );

    return WillPopScope(
      onWillPop: () => _onWillPop(),
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Создание заказа'),
          backgroundColor: Theme.of(context).primaryColor,
          actions: [
            Container(
              child: Stack(
                children: [
                  IconButton(
                    icon: Icon(Icons.shopping_bag_outlined),
                    onPressed: () =>
                        Navigator.pushNamed(context, '/orderReview'),
                    iconSize: 30,
                  ),
                ],
              ),
            )
          ],
        ),
        body: _kTabPages[_currentTabIndex],
        // body: IndexedStack(
        //   index: _currentTabIndex,
        //   children: _kTabPages,
        // ),
        bottomNavigationBar: bottomNavBar,
      ),
    );
  }

这是我的无状态widget:

import 'package:counter/blocs/food/food_bloc.dart';
import 'package:counter/data/repository/food_repository.dart';
import 'package:counter/presentation/widgets/Loading.dart';
import 'package:counter/presentation/widgets/MenuItem.dart';
import 'package:counter/presentation/widgets/network_error.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class FoodCategory extends StatelessWidget {
  final String foodCategory;
  FoodCategory({@required this.foodCategory});

  @override
  Widget build(BuildContext context) {
    FoodRepository foodRepository = FoodRepository(category: this.foodCategory);

    return BlocProvider<FoodBloc>(
      create: (BuildContext context) =>
          FoodBloc(foodRepository: foodRepository)..add(FoodLoadEvent()),
      child: Scaffold(
        body: BlocBuilder<FoodBloc, FoodState>(
          builder: (context, state) {
            if (state is FoodInitial) {
              return Text('Initial state');
            }
            if (state is FoodLoadingState) {
              return CustomLoading();
            }
            if (state is FoodLoadedState) {
              return ListView.builder(
                itemBuilder: (BuildContext context, index) {
                  return MenuItem(foodItem: state.loadedFoodItems[index]);
                },
                itemCount: state.loadedFoodItems.length,
              );
            } else {
              return NetworkErrorWidget();
            }
          },
        ),
      ),
    );
  }
}

但是当我为所有的标签使用不同的小部件时,它已经开始正常工作并刷新。

final _kTabPages = <Widget>[
      NationalFood(foodCategory: 'nationalFood'),
      FastFoodScreen(foodCategory: 'fastFood'),
      DessertsScreen(foodCategory: 'dessert'),
      DrinksScreen(foodCategory: 'drinks'),
    ];
9fkzdhlc

9fkzdhlc1#

FoodCategoryNationalFood小部件的initState中,添加检索数据的函数。

w1jd8yoj

w1jd8yoj2#

由于您将_kTabPages_kBottomNavBarItems初始化放置在build()方法中,因此每当状态发生更改时(更改选项卡时),这些变量都会被分配新值。这就是选项卡不断重新呈现的原因。
要停止这种情况,请将初始化放在initState()中。类似于以下内容:

import 'package:flutter/material.dart';
import 'package:test_flutter_app/test.dart';

class CreateOrder extends StatefulWidget {
  @override
  _CreateOrderState createState() => _CreateOrderState();
}

class _CreateOrderState extends State<CreateOrder> {
  int _currentTabIndex = 0;
  List<Widget> _kTabPages;
  List<BottomNavigationBarItem> _kBottomNavBarItems;
  BottomNavigationBar bottomNavBar;

  _updateTabs() {
    _kTabPages = <Widget>[
      FoodCategory(key: UniqueKey(), foodCategory: 'nationalFood'),
      FoodCategory(key: UniqueKey(), foodCategory: 'fastFood'),
      FoodCategory(key: UniqueKey(), foodCategory: 'dessert'),
      FoodCategory(key: UniqueKey(), foodCategory: 'drinks'),
    ];

    _kBottomNavBarItems = <BottomNavigationBarItem>[
      const BottomNavigationBarItem(
        icon: Icon(Icons.fastfood_outlined),
        label: 'Традиционная',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.alarm),
        label: 'Фаст Фуд',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.food_bank_outlined),
        label: 'Дессерты',
      ),
      const BottomNavigationBarItem(
        icon: Icon(Icons.emoji_food_beverage),
        label: 'Напитки',
      ),
    ];
    bottomNavBar = BottomNavigationBar(
      items: _kBottomNavBarItems,
      currentIndex: _currentTabIndex,
      type: BottomNavigationBarType.fixed,
      onTap: (int index) {
        setState(() => _currentTabIndex = index);
      },
    );
    assert(_kTabPages.length == _kBottomNavBarItems.length);
  }

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

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async => true,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('Создание заказа'),
          backgroundColor: Theme.of(context).primaryColor,
        ),
        body: _kTabPages[_currentTabIndex],
        // body: IndexedStack(
        //   index: _currentTabIndex,
        //   children: _kTabPages,
        // ),
        bottomNavigationBar: bottomNavBar,
      ),
    );
  }
}
lstz6jyr

lstz6jyr3#

我想这是很晚才回答这个问题.我也面临着同样的问题.子部件不重画一旦值在父部件改变.所以我搜索了3天,最后我找到了一个解决方案.
1.已加载具有唯一键的子构件
1.在构建方法内部初始化的子窗口小部件。
在此更改之后,如果父控件中的状态更改,则子控件也会刷新。
谢谢

相关问题