Flutter xóa tất cả các tuyến đường


98

Tôi muốn phát triển một nút đăng xuất sẽ đưa tôi đến lộ trình đăng nhập và xóa tất cả các lộ trình khác khỏi Navigator. Tài liệu này dường như không giải thích cách tạo RoutePredicatehoặc có bất kỳ loại chức năng removeAll nào.

Câu trả lời:


267

Tôi đã có thể thực hiện điều này với mã sau:

Navigator.of(context)
    .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);

Bí mật ở đây là sử dụng một RoutePredicate luôn trả về false (Route<dynamic> route) => false. Trong tình huống này, nó xóa tất cả các tuyến ngoại trừ /logintuyến mới mà tôi đã đẩy.


1
Cảm ơn rất nhiều nó đã hoạt động thành công. Bạn có thể vui lòng gửi một số liên kết, nơi tôi có thể hiểu thêm ....
Pawan

Tôi có một vấn đề với điều này! Trên iOS, bằng cách sử dụng chế độ xem gốc làm tiện ích con, sau khi sử dụng phương pháp của bạn, chế độ xem gốc không xử lý đúng cách và tiếp tục tồn tại, kết quả là tôi có một chế độ xem sẽ không bao giờ được sử dụng nữa đang chạy trong một loại nền và không thể loại bỏ . Điều này dường như chỉ xảy ra trên các thiết bị iOS.
Lorenzo Imperatrice

@LorenzoImperatrice Bạn có tìm thấy bản sửa lỗi cho sự cố này không? Tôi đang gặp vấn đề tương tự
Mateusz Tylman 12/09/19

3
Tôi vẫn có trường hợp mở ngay cả sau khi sử dụng cái này. bất kỳ giải pháp nào khác để đẩy màn hình và loại bỏ phần còn lại của ngăn xếp?
Manoj MM

Làm thế nào chúng ta có thể vượt qua các đối số với cách tiếp cận này.
Developine

78

tôi có thể thực hiện với đoạn mã sau:

 Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute(builder: (context) =>
    LoginScreen()), (Route<dynamic> route) => false),

nếu bạn muốn xóa tất cả các tuyến bên dưới tuyến được đẩy, RoutePredicate luôn trả về false , ví dụ: (Tuyến đường) => false .


24

Một thay thế khác là popUntil()

Navigator.of(context).popUntil(ModalRoute.withName('/root'));

Thao tác này sẽ tắt tất cả các tuyến đường cho đến khi bạn quay lại tuyến đường đã đặt tên.


1
Tôi thích câu trả lời này hơn!
noveleven


10

Trong trường hợp bạn muốn quay lại màn hình cụ thể và bạn không sử dụng bộ định tuyến đã đặt tên, có thể sử dụng phương pháp tiếp theo

Thí dụ:

Navigator.pushAndRemoveUntil(context,
                  MaterialPageRoute(builder: (BuildContext context) => SingleShowPage()),
                  (Route<dynamic> route) => route is HomePage
              );

Với route là HomePage, bạn kiểm tra tên widget của mình.


NoAnimatedRoute là gì? Không thể tìm thấy lớp học có tên như vậy trong Flutter
kashlo

@kashlo Đừng chú ý =) Nó chỉ là triển khai của tôi có thể sử dụng MaterialPageRoute để thay thế. Nhưng tôi đã chỉnh sửa câu trả lời, cảm ơn.
Volodymyr Bilovus

(Route <dynamic> route) => route.isFirst) Nếu một số người muốn xóa cho đến khi lộ trình đầu tiên.
Hussnain Haidar

4

Nếu bạn đang sử dụng nameRoutes, bạn có thể thực hiện việc này bằng cách đơn giản:

Navigator.pushNamedAndRemoveUntil(context, "/login", (Route<dynamic> route) => false);

Trong đó "/ login" là tuyến đường bạn muốn đẩy trên ngăn xếp tuyến đường.

Lưu ý rằng:

Câu lệnh này loại bỏ tất cả các tuyến trong ngăn xếp và biến cái được đẩy trở thành gốc.


3

Tôi không biết lý do tại sao không ai đề cập đến giải pháp sử dụng SchedularBindingInstance , Một chút muộn để đảng tuy nhiên, tôi nghĩ rằng đây sẽ là đúng cách để làm điều đó ban đầu được trả lời tại đây

    SchedulerBinding.instance.addPostFrameCallback((_) async {
                              Navigator.of(context).pushNamedAndRemoveUntil(
                                  '/login',
                                  (Route<dynamic> route) => false);
                            });

Đoạn mã trên xóa tất cả các tuyến đường và điều hướng đến '/ login', điều này cũng làm cho tất cả các khung được hiển thị trước khi điều hướng đến tuyến đường mới bằng cách lên lịch gọi lại


1

Điều này đang làm việc cho tôi. Trên thực tế, tôi đã làm việc với khối nhưng vấn đề của tôi là khối màn hình đăng nhập. Nó không cập nhật sau khi đăng xuất. Nó đang giữ dữ liệu mô hình trước đó. Thậm chí, tôi đã nhập sai mục Đó là sẽ vào Màn hình chính.

Bước 1:

Navigator.of(context).pushNamedAndRemoveUntil(
        UIData.initialRoute, (Route<dynamic> route) => false);

Ở đâu, UIData.initialRoute = "/" or "/login"

Bước 2:

Nó đang hoạt động để làm mới màn hình. Nếu bạn đang làm việc với Bloc thì nó sẽ rất hữu ích.

runApp(MyApp());

Ở đâu, MyApp() is the root class.

Gốc lớp (tức là MyApp) đang

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());

Đây là phương pháp Đăng xuất của tôi ,

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());
  }

0

Không chắc liệu tôi có làm đúng không

nhưng điều này phù hợp với trường hợp sử dụng của tôi là bật lên cho đến khi bằng tiện ích gốc

void popUntilRoot({Object result}) {
    if (Navigator.of(context).canPop()) {
      pop();
      popUntilRoot();
    }
}

0
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);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.