Closed kawi15 closed 2 months ago
If I understand correctly, your problem seems to be in the "context".
Within its onWillPop
function, the context
used in Navigator.of(context).pop();
refers to the root (if we can say so) (the location where the PersistentTabView
is.
Try this, and let me know if you need more help:
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
title: 'Flutter Demo',
debugShowCheckedModeBanner: false,
routes: {
"/home": (context) => const ScreenPage(title: "Home", contentMessage: "Home"),
"/home/second": (context) => const ScreenPage(title: "Home 2nd", contentMessage: "Home 2nd"),
"/search": (context) => const ScreenPage(title: "Search", contentMessage: "Search"),
"/search/second": (context) => const ScreenPage(title: "Search 2nd", contentMessage: "Search 2nd"),
"/profile": (context) => const ScreenPage(title: "Profile", contentMessage: "Profile"),
"/profile/second": (context) => const ScreenPage(title: "Profile 2nd", contentMessage: "Profile 2nd"),
},
home: const MyHomePage(),
);
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void onPopInvoked(bool didPop) {
if (pageController.index == 0) {
DateTime now = DateTime.now();
if (currentBackPressTime == null || now.difference(currentBackPressTime!) > Duration(seconds: 2)) {
currentBackPressTime = now;
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
content: const Text('Press back again to exit'),
duration: const Duration(seconds: 2),
width: MediaQuery.of(context).size.width * 0.9,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(10))),
behavior: SnackBarBehavior.floating,
));
} else {
SystemNavigator.pop();
}
} else {
if (selectedTabContext != null && Navigator.of(selectedTabContext!).canPop()) {
Navigator.of(selectedTabContext!).pop();
} else {
pageController.jumpToTab(0);
}
}
}
DateTime? currentBackPressTime;
BuildContext? selectedTabContext;
final PersistentTabController pageController = PersistentTabController(initialIndex: 0);
@override
Widget build(BuildContext context) => PopScope(
onPopInvoked: onPopInvoked,
canPop: false,
child: PersistentTabView(
controller: pageController,
navBarHeight: 70,
handleAndroidBackButtonPress: false,
// look this VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
selectedTabContext: (context) => selectedTabContext = context,
navBarBuilder: (navBarConfig) => Style4BottomNavBar(
navBarConfig: navBarConfig,
navBarDecoration: const NavBarDecoration(
border: Border(
top: BorderSide(color: Color(0xFFD1D5DB))
),
padding: EdgeInsets.only(bottom: 8),
boxShadow: [
BoxShadow(
offset: Offset(0, 4),
blurRadius: 6,
spreadRadius: -2
)
]
),
),
tabs: [
PersistentTabConfig(
screen: ScreenPage(key: GlobalKey(), title: "Home", contentMessage: "Home 1"),
item: ItemConfig(
activeForegroundColor: const Color(0xFF8430CB),
icon: Icon(Icons.home),
title: 'Home'
)
),
PersistentTabConfig(
screen: ScreenPage(key: GlobalKey(), title: "Search", contentMessage: "Search"),
item: ItemConfig(
activeForegroundColor: const Color(0xFF8430CB),
icon: Icon(Icons.search),
title: 'Search'
)
),
PersistentTabConfig(
screen: ScreenPage(key: GlobalKey(), title: "Profile", contentMessage: "Profile"),
item: ItemConfig(
activeForegroundColor: const Color(0xFF8430CB),
icon: Icon(Icons.person),
title: 'Profile'
)
)
],
),
);
}
class ScreenPage extends StatelessWidget {
final String title;
final String contentMessage;
const ScreenPage({super.key, required this.title, required this.contentMessage});
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: Text(title),
),
body: Container(
width: double.infinity,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(contentMessage),
if (!title.endsWith("2nd"))
TextButton(
onPressed: () {
Navigator.of(context).pushNamed("/${title.toLowerCase()}/second");
},
child: Text("Go to 2nd screen"),
)
],
),
),
);
}
Yes, that was the problem and your solution is great. Thank you very much.
Version
5.2.2
What platforms are you seeing the problem on?
Android
What happened?
I want to have overrided functionality of pressing back button on Android. To do it I need to set
handleAndroidBackButtonPress: false
and implementPopScope
orwillPopScope
function and I did it. Everything is working as I want except one thing. When I go to another page with navBar visible, when I press android back button it's not coming back to previous page, it's closing app, somehowNavigator.of(context).pop()
is executingonWillPop
again.My question is how to back from this page using PopScope? When I set
handleAndroidBackButtonPress: true
it is working, but then it's remembering switched tabs and as you can see in my code I want to back always to 0 index, not the previous one, so this option is not good also.Long story short:
Navigator.of(context).pop()
not working properly in PopScope, when used with button it is working.Steps to reproduce
Code to reproduce the problem
Relevant log output
No response
Screenshots
No response