#flutter #dart #flutter-bottomnavigation
#flutter #dart #flutter-bottomnavigation
Вопрос:
Я использую эту библиотеку persistent_bottom_nav_bar
для отображения нижней панели навигации даже при переходе на новый экран. Теперь есть две основные страницы Page1
и Page2
, Page1
использует значок home
, где, как Page2
использует значок search
. В Page1
содержит кнопку, которая переходит к новому экрану с именем as NewPage
. Чего я хотел добиться, так это если я перейду к NewPage
from Page1
и если я решу вернуться к предыдущему экрану, Page1
нажав на homeicon
который внизу. Итак, как я могу нажать на нижний элемент и вернуться к предыдущему экрану? Надеюсь, вы поняли мой вопрос
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: HomeScaffold(),
);
}
}
class HomeScaffold extends StatefulWidget {
@override
_HomeScaffoldState createState() => _HomeScaffoldState();
}
class _HomeScaffoldState extends State<HomeScaffold> {
late PersistentTabController _controller;
@override
void initState() {
super.initState();
_controller = PersistentTabController(initialIndex: 0);
}
List<Widget> _buildScreens() {
return [
Page1(),
Page2(),
];
}
List<PersistentBottomNavBarItem> _navBarsItems() {
return [
_buildBottomNavBarItem('Page 1', Icons.home),
_buildBottomNavBarItem('Page 2', Icons.search),
];
}
@override
Widget build(BuildContext context) {
return PersistentTabView.custom(
context,
controller: _controller,
screens: _buildScreens(),
confineInSafeArea: true,
itemCount: 2,
handleAndroidBackButtonPress: true,
stateManagement: true,
screenTransitionAnimation: ScreenTransitionAnimation(
animateTabTransition: true,
curve: Curves.ease,
duration: Duration(milliseconds: 200),
),
customWidget: CustomNavBarWidget(
items: _navBarsItems(),
onItemSelected: (index) {
setState(() {
_controller.index = index; // go back to previous screen if i navigate to new screen
});
},
selectedIndex: _controller.index,
),
// ),
);
}
}
class CustomNavBarWidget extends StatelessWidget {
final int? selectedIndex;
final List<PersistentBottomNavBarItem> items;
final ValueChanged<int>? onItemSelected;
CustomNavBarWidget({
Key? key,
this.selectedIndex,
required this.items,
this.onItemSelected,
});
Widget _buildItem(PersistentBottomNavBarItem item, bool isSelected) {
return Container(
alignment: Alignment.center,
height: kBottomNavigationBarHeight,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: IconTheme(
data: IconThemeData(
size: 26.0,
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary == null
? item.activeColorPrimary
: item.inactiveColorPrimary),
child: isSelected ? item.icon : item.inactiveIcon ?? item.icon,
),
),
Padding(
padding: const EdgeInsets.only(top: 5.0),
child: Material(
type: MaterialType.transparency,
child: FittedBox(
child: Text(
item.title!,
style: TextStyle(
color: isSelected
? (item.activeColorSecondary == null
? item.activeColorPrimary
: item.activeColorSecondary)
: item.inactiveColorPrimary,
fontWeight: FontWeight.w400,
fontSize: 12.0),
)),
),
)
],
),
);
}
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
child: Container(
width: double.infinity,
height: kBottomNavigationBarHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: items.map((item) {
int index = items.indexOf(item);
return Flexible(
child: GestureDetector(
onTap: () {
this.onItemSelected!(index);
},
child: _buildItem(item, selectedIndex == index),
),
);
}).toList(),
),
),
);
}
}
PersistentBottomNavBarItem _buildBottomNavBarItem(String title, IconData icon) {
return PersistentBottomNavBarItem(
icon: Icon(icon),
title: title,
activeColorPrimary: Colors.indigo,
inactiveColorPrimary: Colors.grey,
);
}
class Page1 extends StatefulWidget {
const Page1({Key? key}) : super(key: key);
@override
_Page1State createState() => _Page1State();
}
class _Page1State extends State<Page1> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: Container(
child: Center(
child: TextButton(
onPressed: () {
Navigator.push(
context, CupertinoPageRoute(builder: (context) => NewPage()));
},
child: Text('Click'),
),
),
),
);
}
}
class Page2 extends StatefulWidget {
const Page2({Key? key}) : super(key: key);
@override
_Page2State createState() => _Page2State();
}
class _Page2State extends State<Page2> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.red,
body: Container(),
);
}
}
class NewPage extends StatefulWidget {
const NewPage({Key? key}) : super(key: key);
@override
_NewPageState createState() => _NewPageState();
}
class _NewPageState extends State<NewPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(),
);
}
}
Ответ №1:
Вы пробовали просто использовать встроенную Navigator.of(context).pop()
функцию в качестве onPressed
обратного вызова?
Комментарии:
1. Да, я пробовал это, но когда я нажимаю
home icon
внизу, экран становится черным.onItemSelected: (index) { setState(() { _controller.index = index; Navigator.of(context).pop(); }); },
2. Можете ли вы попробовать это со своей стороны, может быть, я делаю это не с той стороны.