问题描述
我正在使用颤动的底部导航栏。我想在切换选项卡时刷新每个选项卡。首先,我尝试为所有选项卡重用一个无状态小部件。但它正在重新渲染页面。我的代码如下:
extract(lst,3)
print(output)
>>> [1,2,3,4,5,6,7,8]
这是我的无状态小部件:
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,);
}
但是当我为所有选项卡使用不同的小部件时,它开始正常工作并刷新。
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();
}
},);
}
}
解决方法
在 initState
或 FoodCategory
小部件的 NationalFood
中,添加检索数据的函数。
由于您将 _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: 'dessert'),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,);
}
}