我使用bmnav来实现底部导航栏。 这是我的实现。
main.dart
class MainWidgetState extends State<MainWidget> {
@override
void initState(){
super.initState();
}
int currentTab = 0;
final List<Widget> screens = [
MapSample(), Workouts(), Account()
];
Widget currentScreen = MapSample();
final PageStorageBucket bucket = PageStorageBucket();
@override
Widget build(BuildContext ctx) {
return Scaffold(
body: PageStorage(child: currentScreen, bucket: bucket),
bottomNavigationBar: SizedBox(height: 45,
child: bmnav.BottomNav(
index: currentTab,
onTap: (i) {
setState(() {
currentTab = i;
currentScreen = screens[i];
});
},
labelStyle: bmnav.LabelStyle(visible: true,
items: [
bmnav.BottomNavItem(OMIcons.map, label: 'Map'),
bmnav.BottomNavItem(OMIcons.cast, label: 'Workouts'),
bmnav.BottomNavItem(OMIcons.textsms, label: 'Account'),
],
),
),
);
}
}
当我从索引屏幕切换到其他屏幕并返回索引屏幕时,索引屏幕将始终重建。
如果要更换屏幕,我希望屏幕保持活动状态。我该怎么办?
答案 0 :(得分:1)
嗨,我已经实现了在BottomNavigationBar的选项卡更改时禁用重建页面的功能。
我还在下面附加了gif:
下面是带有3个选项卡的完整示例,该示例具有其自己的变量,可以使用保留值进行更新,并在更改选项卡时保持活动状态:
import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_demo_app/list.dart';
import 'package:bmnav/bmnav.dart' as bmnav;
MyHomeMapSample valMapSample = null;
MyHomeWorkouts valWorkouts = null;
MyHomeAccount valAccount = null;
MapSample mapSample = null;
Workouts workouts = null;
Account account = null;
Widget currentScreen = null;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
ButtonsLists.context = context;
currentScreen = MyHomeMapSample();
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
void initState(){
super.initState();
debugPrint("currentTab: _MyHomePageState super.initState();");
}
int currentTab = 0;
final PageStorageBucket bucket = PageStorageBucket();
@override
Widget build(BuildContext ctx) {
debugPrint('currentTab: $currentTab');
return Scaffold(
body: PageStorage(child: currentScreen, bucket: bucket),
bottomNavigationBar: SizedBox(height: 58,
child: bmnav.BottomNav(
index: currentTab,
onTap: (i) {
setState(() {
currentTab = i;
currentScreen = getWidget(context, i);
debugPrint('inner currentTab: $currentTab');
debugPrint('inner currentScreen: $currentScreen');
});
},
labelStyle: bmnav.LabelStyle(visible: true),
items: [
bmnav.BottomNavItem(Icons.map, label: 'Map'),
bmnav.BottomNavItem(Icons.cast, label: 'Workouts'),
bmnav.BottomNavItem(Icons.textsms, label: 'Account'),
],
),
),
resizeToAvoidBottomPadding: true,
);
}
Widget getWidget(BuildContext context, int i){
if(i==0){
if(valMapSample == null){
valMapSample = MyHomeMapSample();
mapSample = valMapSample.createState();
return valMapSample;
}else{
return mapSample.build(context);
}
}
else if(i==1){
if(valWorkouts == null){
valWorkouts = MyHomeWorkouts();
workouts = valWorkouts.createState();
return valWorkouts;
}else{
return workouts.build(context);
}
}else if(i==2){
if(valAccount == null){
valAccount = MyHomeAccount();
account = valAccount.createState();
return valAccount;
}else{
return account.build(context);
}
}
}
}
class MyHomeMapSample extends StatefulWidget {
MyHomeMapSample({Key key}) : super(key: key);
@override
MapSample createState() => MapSample();
}
class MapSample extends State<MyHomeMapSample> with AutomaticKeepAliveClientMixin {
var myVariable = 0;
@override
void initState(){
super.initState();
debugPrint('current: MapSample: initState() called!');
}
@override
Widget build(BuildContext context) {
myVariable = myVariable + 1;
return Scaffold(
appBar: AppBar(
title: Text('MapSample'),
),
body: Center(
child: Text('MapSample details + $myVariable'),
),
resizeToAvoidBottomPadding: true,
);
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
class MyHomeWorkouts extends StatefulWidget {
MyHomeWorkouts({Key key}) : super(key: key);
@override
Workouts createState() => Workouts();
}
class Workouts extends State<MyHomeWorkouts> with AutomaticKeepAliveClientMixin {
var myVariable = 0;
@override
void initState(){
super.initState();
debugPrint('current: Workouts: initState() called!');
}
@override
Widget build(BuildContext context) {
myVariable = myVariable + 1;
return Scaffold(
appBar: AppBar(
title: Text('Workouts'),
),
body: Center(
child: Text('Workouts details + $myVariable'),
),
resizeToAvoidBottomPadding: true,
);
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
class MyHomeAccount extends StatefulWidget {
MyHomeAccount({Key key}) : super(key: key);
@override
Account createState() => Account();
}
class Account extends State<MyHomeAccount> with AutomaticKeepAliveClientMixin {
var myVariable = 0;
@override
void initState(){
super.initState();
debugPrint('current: Account: initState() called!');
}
@override
Widget build(BuildContext context) {
myVariable = myVariable + 1;
return Scaffold(
appBar: AppBar(
title: Text('Account'),
),
body: Center(
child: Text('Account details + $myVariable'),
),
resizeToAvoidBottomPadding: true,
);
}
@override
// TODO: implement wantKeepAlive
bool get wantKeepAlive => true;
}
我所做的是在全局创建“ StatefulWidget
”和“ State<>
”类对象,然后借助“ createState()
”的“ StatefulWidget
”方法和“ .build(context)
”类的“ State<>
”方法,
我已阻止调用“ initState()
”方法并更新没有它的小部件。
我也用“ with AutomaticKeepAliveClientMixin
”来表示“ State<>
”,这将试图使对象保持活动状态。
希望这会有所帮助:)