modular
modular copied to clipboard
flutter_modular - Navigation open two pages in same time
When we click on two points on the screen simultaneously to do navigation (with Modular.pushNamed ), it opens two pages together.
Using flutter's native navigation, the problem doesn't happen
How can I deal with this?
https://user-images.githubusercontent.com/39360514/191567777-cd4ac566-3973-4b9e-a185-fbb91ae8c330.mp4
I found a way to solve it, but I don't know if it's the best
I added a variable to control the current state pushing
, I change it to true after starting the navigation, and at the end I change it to false again.
@override
Future<T?> pushNamed<T extends Object?>(String routeName,
{Object? arguments, bool forRoot = false}) async {
if (pushing) return null;
pushing = true;
final popComplete = Completer();
var book = await parser.selectBook(routeName,
arguments: arguments, popCallback: popComplete.complete);
if (forRoot) {
book = currentConfiguration!.copyWith(routes: [
...currentConfiguration!.routes,
book.routes.last.copyWith(schema: '')
]);
await setNewRoutePath(book);
} else {
final list = [...currentConfiguration!.routes];
for (var route in book.routes.reversed) {
if (list
.firstWhere(
(element) => element.uri.toString() == route.uri.toString(),
orElse: () => ParallelRoute.empty())
.name ==
'') {
list.add(route);
}
}
if (currentConfiguration!.routes.length == list.length) {
list.add(book.routes.last);
}
await setNewRoutePath(book.copyWith(routes: list));
}
pushing = false;
return await popComplete.future;
}
What do you think?
Any updates?
This error persist on v6?
This error persist on v6?
Yes, i did the test on v6 and the problem persists.
Do you have any examples?
Do you have any examples?
When clicking both buttons at the same time, both navigations are performed, something that doesn't happen with the standard navigation.
Modular
https://github.com/Flutterando/modular/assets/18041980/d152af1b-fdf3-4dbd-a363-306498e31782
Flutter navigation
https://github.com/Flutterando/modular/assets/18041980/567f0d38-e27d-4e69-a6bc-225777fb4c7d
Flutter Modular
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 100,
child: ElevatedButton(
onPressed: () {
Modular.to.pushNamed('/test1');
},
child: const Icon(Icons.remove),
),
),
Positioned(
bottom: 100,
child: ElevatedButton(
onPressed: () {
Modular.to.pushNamed('/test2');
},
child: const Icon(Icons.add),
),
),
],
),
);
}
}
Flutter Navigation
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
alignment: Alignment.center,
children: [
Positioned(
top: 100,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SecondPage(),
),
);
},
child: const Icon(Icons.remove),
),
),
Positioned(
bottom: 100,
child: ElevatedButton(
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const ThirdPage(),
),
);
},
child: const Icon(Icons.add),
),
),
],
),
);
}
This error persist on v6?
I looked at the current code and it follows the same without changes. What do you think of my previous suggestion? I based it on the navigator that uses status to validate
Flutter Modular
class HomePage extends StatefulWidget { const HomePage({super.key}); @override _HomePageState createState() => _HomePageState(); } class _HomePageState extends State<HomePage> { @override Widget build(BuildContext context) { return Scaffold( body: Stack( alignment: Alignment.center, children: [ Positioned( top: 100, child: ElevatedButton( onPressed: () { Modular.to.pushNamed('/test1'); }, child: const Icon(Icons.remove), ), ), Positioned( bottom: 100, child: ElevatedButton( onPressed: () { Modular.to.pushNamed('/test2'); }, child: const Icon(Icons.add), ), ), ], ), ); } }
Flutter Navigation
class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { @override Widget build(BuildContext context) { return Scaffold( body: Stack( alignment: Alignment.center, children: [ Positioned( top: 100, child: ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const SecondPage(), ), ); }, child: const Icon(Icons.remove), ), ), Positioned( bottom: 100, child: ElevatedButton( onPressed: () { Navigator.of(context).push( MaterialPageRoute( builder: (context) => const ThirdPage(), ), ); }, child: const Icon(Icons.add), ), ), ], ), ); }
Can you provide a complete example?
I'm running into this issue as well. This issue has been the most painful of all because users can open multiple items on a listview and open multiple navigations. Even if this issue is fixed on some recent version, I won't be able to migrate because there is not enough documentation for migration from v5 to v6 as for the scenarios mentioned in this issue #901.
@jacobaraujo7 Can you provide a complete example?
Flutter Standard Navigation:
import 'package:flutter/material.dart';
void main() {
runApp(const AppWidget());
}
class AppWidget extends StatelessWidget {
const AppWidget({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => const HomePage(),
'/first': (context) => const FirstPage(),
'/second': (context) => const SecondPage(),
},
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Expanded(
child: GestureDetector(
onTap: () async {
print('TAP 1');
Navigator.pushNamed(context, '/first');
},
child: Container(color: Colors.blue),
),
),
Expanded(
child: GestureDetector(
onTap: () async {
print('TAP 2');
Navigator.pushNamed(context, '/second');
},
child: Container(color: Colors.red),
),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
const FirstPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Return 1'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
const SecondPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pop(context),
child: const Text('Return 2'),
),
),
);
}
}
Modular Navigation:
import 'package:flutter/material.dart';
import 'package:flutter_modular/flutter_modular.dart';
void main() {
runApp(ModularApp(module: AppModule(), child: const AppWidget()));
}
class AppWidget extends StatelessWidget {
const AppWidget({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: Modular.routerConfig,
);
}
}
class AppModule extends Module {
@override
void binds(i) {}
@override
void routes(r) {
r.child('/', child: (context) => const HomePage());
r.child('/first', child: (context) => const FirstPage());
r.child('/second', child: (context) => const SecondPage());
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Expanded(
child: GestureDetector(
onTap: () {
print('TAP 1');
Modular.to.pushNamed('/first');
},
child: Container(color: Colors.blue),
),
),
Expanded(
child: GestureDetector(
onTap: () async {
print('TAP 2');
Modular.to.pushNamed('/second');
},
child: Container(color: Colors.red),
),
),
],
),
));
}
}
class FirstPage extends StatelessWidget {
const FirstPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Modular.to.pop(),
child: const Text('Return 1'),
),
),
);
}
}
class SecondPage extends StatelessWidget {
const SecondPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () => Modular.to.pop(),
child: const Text('Return 2'),
),
),
);
}
}