我正在使用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'),
];
3条答案
按热度按时间9fkzdhlc1#
在
FoodCategory
或NationalFood
小部件的initState
中,添加检索数据的函数。w1jd8yoj2#
由于您将
_kTabPages
和_kBottomNavBarItems
初始化放置在build()
方法中,因此每当状态发生更改时(更改选项卡时),这些变量都会被分配新值。这就是选项卡不断重新呈现的原因。要停止这种情况,请将初始化放在
initState()
中。类似于以下内容:lstz6jyr3#
我想这是很晚才回答这个问题.我也面临着同样的问题.子部件不重画一旦值在父部件改变.所以我搜索了3天,最后我找到了一个解决方案.
1.已加载具有唯一键的子构件
1.在构建方法内部初始化的子窗口小部件。
在此更改之后,如果父控件中的状态更改,则子控件也会刷新。
谢谢