OverView
Что ж, есть много способов реализовать BottomNavigationBar
во Flutter. Но использование метода IndexedStack
создало бы все экраны BottomNavigationBar
в начале. Это можно исправить с помощью TabBarView
.
Вот как я реализовал BottomNavigationBar
в своем приложении, используя CupertinoTabBar
и PageView
, так как вначале будет только один экран. А также использование AutomaticKeepAliveMixin
, так как это не позволит воссоздать экраны снова.
Ключевые точки
PageView
с PageController
, с помощью которого вы можете легко переключаться между экранами.
AutomaticKeepAliveClientMixin
не позволяет воссоздавать экраны, поэтому нет необходимости использовать IndexedStack
.
- Используйте
Provider
и Consumer
, чтобы воссоздать только CupertinoTabBar
при изменении currentIndex
. Вместо использования setState()
, поскольку он воссоздает весь экран, позволяя перестроить все виджеты. Но здесь были использованы Provider
для воссоздания только TabBar
.
Пример кода
Домашняя страница (BottomNavigtionBar
)
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
PageController _pageController;
@override
void initState() {
_pageController = PageController();
super.initState();
}
@override
void dispose() {
_pageController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Wrapping the CupertinoTabBar in Consumer so that It only get
// recreated.
bottomNavigationBar: Consumer<HomeVM>(
builder: (context, model, child) {
return CupertinoTabBar(
backgroundColor: Colors.white10,
currentIndex: model.currentPage,
onTap: (index) {
index == model.currentPage
? print('same screen')
: _pageController.jumpToPage(
index,
);
model.changePage(index);
},
items: bottomNavItems);
},
),
body:ChangeNotifierProvider(
create: (_) => locator<HelpVM>(),
child: SafeArea(
top: false,
child: PageView(
controller: _pageController,
physics: NeverScrollableScrollPhysics(),
children: <Widget>[
FrontScreen(),
WorkRootScreen(),
HelpScreen(),
AccountScreen(),
],
),
),
),
);
}
const List<BottomNavigationBarItem> bottomNavItems =
<BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: const Icon(
FontAwesomeIcons.home,
),
),
//...... bottomNavigationBarItems
];
}
HomeVM (Использование Provider
для изменения индекса и воссоздания только TabBar
с использованием Consumer
)
class HomeVM extends ChangeNotifier {
int _currentPage = 0;
int get currentPage => _currentPage;
void changePage(int index) {
this._currentPage = index;
notifyListeners();
}
}
FrontScreen (здесь мы используем AutomaticKeepAliveClientMixin
, чтобы сохранить состояние, не воссоздавая виджет)
class FrontScreen extends StatefulWidget {
@override
_FrontScreenState createState() => _FrontScreenState();
}
class _FrontScreenState extends State<FrontScreen>
with AutomaticKeepAliveClientMixin {
@override
Widget build(BuildContext context) {
// VIMP to Add this Line.
super.build(context);
return SafeArea(
// Your Screen Code
);
}
@override
bool get wantKeepAlive => true;
}
person
DIVYANSHU SAHU
schedule
18.08.2020