ฉันต้องการพัฒนาปุ่มออกจากระบบที่จะส่งฉันไปยังเส้นทางการเข้าสู่ระบบและลบเส้นทางอื่น ๆ ทั้งหมดออกจากไฟล์Navigator
. เอกสารประกอบไม่ได้อธิบายวิธีสร้างRoutePredicate
หรือมีฟังก์ชัน removeAll ประเภทใด ๆ
ฉันต้องการพัฒนาปุ่มออกจากระบบที่จะส่งฉันไปยังเส้นทางการเข้าสู่ระบบและลบเส้นทางอื่น ๆ ทั้งหมดออกจากไฟล์Navigator
. เอกสารประกอบไม่ได้อธิบายวิธีสร้างRoutePredicate
หรือมีฟังก์ชัน removeAll ประเภทใด ๆ
คำตอบ:
ฉันสามารถทำสิ่งนี้ได้ด้วยรหัสต่อไปนี้:
Navigator.of(context)
.pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
ความลับที่นี่คือการใช้ RoutePredicate ที่ส่งคืนเท็จ(Route<dynamic> route) => false
เสมอ ในสถานการณ์นี้จะลบเส้นทางทั้งหมดยกเว้นเส้นทางใหม่ที่/login
ฉันผลักดัน
ฉันสามารถทำได้โดยใช้ข้อมูลโค้ดต่อไปนี้:
Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
LoginScreen()), (Route<dynamic> route) => false),
ถ้าคุณต้องการที่จะลบทุกเส้นทางด้านล่างเส้นทางผลัก, RoutePredicateเสมอกลับเท็จเช่น(เส้นทางเส้นทาง) => เท็จ
อีกทางเลือกหนึ่งคือ popUntil()
Navigator.of(context).popUntil(ModalRoute.withName('/root'));
การดำเนินการนี้จะปิดเส้นทางทั้งหมดจนกว่าคุณจะกลับมาที่เส้นทางที่ระบุไว้
pushAndRemoveUnit()
ทางออกก็คือการใช้งาน หากต้องการลบเส้นทางอื่น ๆ ทั้งหมดให้ใช้ModalRoute.withName('/')
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (BuildContext context) => Login()),
ModalRoute.withName('/'));
อ้างอิง: https://api.flutter.dev/flutter/widgets/NavigatorState/pushAndRemoveUntil.html
ในกรณีที่คุณต้องการกลับไปที่หน้าจอนั้นและคุณไม่ได้ใช้เราเตอร์ที่มีชื่อสามารถใช้แนวทางถัดไปได้
ตัวอย่าง:
Navigator.pushAndRemoveUntil(context,
MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()),
(Route<dynamic> route) => route is HomePage
);
ด้วยเส้นทางคือ HomePageคุณตรวจสอบชื่อวิดเจ็ตของคุณ
หากคุณกำลังใช้ namedRoutes คุณสามารถทำได้โดย:
Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);
โดยที่"/ login"คือเส้นทางที่คุณต้องการผลักดันบนกองเส้นทาง
โปรดทราบว่า:
คำสั่งนี้จะลบเส้นทางทั้งหมดในสแต็กและทำให้เส้นทางที่พุชเป็นรูท
ฉันไม่รู้ว่าทำไมไม่มีใครพูดถึงวิธีแก้ปัญหาโดยใช้SchedularBindingInstanceแม้ว่าจะสายไปหน่อยฉันคิดว่านี่จะเป็นวิธีที่ถูกต้องในการตอบแต่แรกที่นี่
SchedulerBinding.instance.addPostFrameCallback((_) async {
Navigator.of(context).pushNamedAndRemoveUntil(
'/login',
(Route<dynamic> route) => false);
});
รหัสด้านบนจะลบเส้นทางและการนำทางทั้งหมดไปที่ '/ เข้าสู่ระบบ' สิ่งนี้ยังทำให้เกินกว่าที่เฟรมทั้งหมดจะแสดงผลก่อนที่จะนำทางไปยังเส้นทางใหม่โดยกำหนดเวลาการโทรกลับ
นี่ใช้งานได้สำหรับฉัน อันที่จริงฉันทำงานกับกลุ่มแต่ปัญหาของฉันคือกลุ่มหน้าจอเข้าสู่ระบบ ไม่ได้อัปเดตหลังจากออกจากระบบ มันถือข้อมูลรุ่นก่อนหน้า แม้ฉันป้อนรายการผิดมันกำลังไปที่หน้าจอหลัก
ขั้นตอนที่ 1:
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
ที่ไหน
UIData.initialRoute = "/" or "/login"
ขั้นตอนที่ 2:
กำลังรีเฟรชหน้าจอ หากคุณกำลังทำงานกับ Bloc มันจะมีประโยชน์มาก
runApp(MyApp());
ที่ไหน
MyApp() is the root class.
ระดับราก (เช่นแอปของฉัน)รหัส
class MyApp extends StatelessWidget {
final materialApp = Provider(
child: MaterialApp(
title: UIData.appName,
theme: ThemeData(accentColor: UIColor().getAppbarColor(),
fontFamily: UIData.quickFont,
),
debugShowCheckedModeBanner: false,
//home: SplashScreen(),
initialRoute: UIData.initialRoute,
routes: {
UIData.initialRoute: (context) => SplashScreen(),
UIData.loginRoute: (context) => LoginScreen(),
UIData.homeRoute: (context) => HomeScreen(),
},
onUnknownRoute: (RouteSettings rs) => new MaterialPageRoute(
builder: (context) => new NotFoundPage(
appTitle: UIData.coming_soon,
icon: FontAwesomeIcons.solidSmile,
title: UIData.coming_soon,
message: "Under Development",
iconColor: Colors.green,
)
)));
@override
Widget build(BuildContext context) {
return materialApp;
}
}
void main() => runApp(MyApp());
นี่คือวิธีการออกจากระบบของฉัน
void logout() async {
SharedPreferences preferences = await SharedPreferences.getInstance();
preferences.clear();
// TODO: we can use UIData.loginRoute instead of UIData.initialRoute
Navigator.of(context).pushNamedAndRemoveUntil(
UIData.initialRoute, (Route<dynamic> route) => false);
//TODO: It's working as refresh the screen
runApp(MyApp());
}
ไม่แน่ใจว่าทำถูกไหม
แต่สิ่งนี้เหมาะกับการใช้งานของฉันในการ popping จนถึงโดยวิดเจ็ตรูท
void popUntilRoot({Object result}) {
if (Navigator.of(context).canPop()) {
pop();
popUntilRoot();
}
}
to clear route -
onTap: () {
//todo to clear route -
Navigator.of(context).pop();
Navigator.push(context, MaterialPageRoute(builder: (context) => UpdateEmployeeUpdateDateActivity(_token),));
widget.listener.onEmployeeDateClick(_day,_month, _year);
}