Flutter는 모든 경로를 제거합니다.


107

로그인 경로로 이동하고 .NET Framework에서 다른 모든 경로를 제거하는 로그 아웃 버튼을 개발하고 싶습니다 Navigator. 문서는 만드는 방법을 설명하지 않거나 RoutePredicate일종의 removeAll 함수를 갖는 것 같습니다 .

답변:


277

다음 코드로이 작업을 수행 할 수있었습니다.

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

여기서 비밀은 항상 false를 반환하는 RoutePredicate를 사용하는 것입니다 (Route<dynamic> route) => false. 이 상황에서는 /login내가 푸시 한 새 경로를 제외한 모든 경로가 제거됩니다 .


1
성공적으로 작동했습니다. 좀 더 이해할 수있는 링크를 보내 주시겠습니까? ...
Pawan

나는 이것에 문제가있다! iOS에서 네이티브 뷰를 위젯으로 사용하면 메서드를 사용한 후 네이티브 뷰가 제대로 처리되지 않고 계속 존재하므로 일종의 백그라운드에서 다시 실행되지 않고 삭제가 불가능한 뷰가 있습니다. . 이것은 iOS 기기에서만 발생하는 것 같습니다.
Lorenzo Imperatrice

@LorenzoImperatrice이 문제에 대한 해결책을 찾았습니까? 비슷한 문제가 있습니다
Mateusz Tylman 19 년

3
이것을 사용한 후에도 여전히 인스턴스가 열려 있습니다. 화면을 밀고 나머지 스택을 제거하는 다른 솔루션이 있습니까?
Manoj MM

이 접근법으로 어떻게 주장을 전달할 수 있습니까?
개발

86

다음 코드 스 니펫으로 수행 할 수 있습니다.

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

푸시 된 경로 아래의 모든 경로를 제거하려면 RoutePredicate는 항상 false를 반환 합니다 ( 예 : (Route route) => false) .


27

또 다른 대안은 popUntil()

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

이렇게하면 명명 된 경로로 돌아올 때까지 모든 경로가 표시됩니다.


1
나는이 대답을 선호한다!
noveleven


13

특정 화면으로 돌아가고 싶고 명명 된 라우터를 사용하지 않는 경우 다음 방법을 사용할 수 있습니다.

예:

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

함께 홈페이지 경로입니다 당신이 위젯의 이름을 확인합니다.


NoAnimatedRoute 란 무엇입니까? 플러터에 같은 이름을 가진 클래스를 찾을 수 없습니다
kashlo

@kashlo주의를 기울이지 마십시오 =) 내 구현은 대신 MaterialPageRoute를 사용할 수 있습니다. 하지만 답을 수정했습니다. 감사합니다.
Volodymyr Bilovus

(Route <dynamic> route) => route.isFirst) 일부가 첫 번째 경로까지 제거하려는 경우.
Hussnain Haidar

7

namedRoutes를 사용하는 경우 다음과 같이 간단히 수행 할 수 있습니다.

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

여기서 "/ login" 은 경로 스택에 푸시하려는 경로입니다.

참고 :

이 문은 스택의 모든 경로를 제거하고 푸시 된 경로를 루트로 만듭니다.


5

아무도 SchedularBindingInstance를 사용하여 솔루션을 언급하지 않은 이유를 모르겠습니다. 하지만 파티에 조금 늦었지만 이것이 원래 여기에서 대답 한 올바른 방법이라고 생각합니다 .

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

위의 코드는 '/ login'에 대한 모든 경로와 탐색을 제거합니다. 이것은 또한 콜백을 예약하여 새 경로로 이동하기 전에 모든 프레임이 렌더링되도록합니다.


2

이것은 나를 위해 일하고 있습니다. 사실 저는 bloc 과 함께 일하고 있었지만 제 문제는 로그인 화면 블록이었습니다. 로그 아웃 후 업데이트되지 않았습니다. 이전 모델 데이터를 보유하고있었습니다. 그래도 잘못된 항목을 입력했는데 홈 화면으로 이동했습니다.

1 단계:

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

어디, UIData.initialRoute = "/" or "/login"

2 단계:

화면을 새로 고침하는 중입니다. Bloc과 함께 일한다면 매우 도움이 될 것입니다.

runApp(MyApp());

어디, MyApp() is the root class.

루트 클래스 (예 : MyApp) 코드

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

0

내가이 일을 제대로하고 있는지 확실하지 않음

하지만 이것은 루트 위젯까지 팝업의 내 사용 사례에 적합합니다.

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);
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.