Flutter tüm rotaları kaldır


98

Beni oturum açma rotasına gönderecek ve diğer tüm rotaları ’dan kaldıracak bir çıkış düğmesi geliştirmek istiyorum Navigator. Belgeler, bir RoutePredicateremoveAll işlevinin nasıl yapılacağını veya herhangi bir türden bir removeAll işlevine sahip olduğunu açıklamıyor gibi görünüyor .

Yanıtlar:


267

Bunu aşağıdaki kodla başarabildim:

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

Buradaki sır, her zaman yanlış döndüren bir RoutePredicate kullanmaktır (Route<dynamic> route) => false. Bu durumda, ittiğim yeni /loginrota dışındaki tüm rotaları kaldırır .


1
Çok teşekkürler, başarıyla çalıştı. Lütfen daha fazla anlayabileceğim bir bağlantı gönderebilir misiniz ...
Pawan

Bununla bir problemim var! İOS'ta, widget olarak yerel bir görünüm kullandığınızda, yönteminizi kullandıktan sonra yerel görünüm düzgün bir şekilde atılmaz ve var olmaya devam eder, sonuç olarak bir daha asla kullanılmayacak bir arka planda çalışan ve atılması imkansız bir görünüme sahibim . Bu sadece iOS cihazlarda gerçekleşiyor gibi görünüyor.
Lorenzo Imperatrice

@LorenzoImperatrice Bu sorun için düzeltme buldunuz mu? Ben de benzer bir sorun yaşıyorum
Mateusz Tylman

3
Bunu kullandıktan sonra bile açık örneklerim var. ekranı itmek ve yığının geri kalanını çıkarmak için başka bir çözüm var mı?
Manoj MM

Bu yaklaşımla nasıl tartışabiliriz?
Developine

78

aşağıdaki kod parçacığı ile yapabilirim:

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

İtilen rotanın altındaki tüm rotayı kaldırmak istiyorsanız, RoutePredicate her zaman yanlış döndürür , örneğin (Rota rotası) => yanlış .


24

Başka bir alternatif ise popUntil()

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

Bu, adlandırılan rotaya dönene kadar tüm rotaları kapatacaktır.


1
Bu cevabı tercih ederim!
noveleven


10

Belirli bir ekrana geri dönmek istemeniz ve adlandırılmış yönlendiriciyi kullanmamanız durumunda sonraki yaklaşımı kullanabilirsiniz.

Misal:

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

İle Ana rota olduğunu sen Widget'ınızın adını kontrol edin.


NoAnimatedRoute nedir? Flutter'da böyle bir isimde sınıf bulamıyorum
kashlo

@kashlo Dikkat etmeyin =) Sadece benim uygulamam bunun yerine MaterialPageRoute kullanabilir. Ama cevabı düzenledim, teşekkürler.
Volodymyr Bilovus

(Route <dynamic> route) => route.isFirst) Bazıları ilk rotaya kadar kaldırmak istiyorsa.
Hussnain Haydar

4

NamedRoutes kullanıyorsanız, bunu basitçe yapabilirsiniz:

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

Nerede "/ login" rota yığını üzerinde itmek isteyen yoldur.

Bunu not et :

Bu ifade yığındaki tüm yolları kaldırır ve itileni kök yapar.


3

Neden kimsenin SchedularBindingInstance kullanarak çözümden bahsetmediğini bilmiyorum , Partiye biraz geç olsa da, bence bunu yapmanın doğru yolu burada cevaplandı.

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

Yukarıdaki kod, '/ login' için tüm rotaları ve naviagtes'i kaldırır, bu aynı zamanda bir geri arama planlayarak yeni rotaya gitmeden önce tüm çerçevelerin oluşturulmasını sağlar.


1

Bu benim için çalışıyor. Aslında bloc ile çalışıyordum ama sorunum giriş ekranı bloğuydu. Oturumu kapattıktan sonra güncellenmiyordu. Önceki model verilerini tutuyordu. Hatta yanlış girişe girdim, Ana Ekrana gidiyordu.

Aşama 1:

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

nerede, UIData.initialRoute = "/" or "/login"

Adım 2:

Ekranı yenilemeye çalışıyor. Bloc ile çalışıyorsanız, çok yardımcı olacaktır.

runApp(MyApp());

nerede, MyApp() is the root class.

Kök sınıf (yani Uygulamam) kodu

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

İşte My Logout yöntemi,

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

Bunu doğru yapıp yapmadığımdan emin değilim

ancak bu, kök pencere aracına kadar patlama yapma durumuma uyuyor

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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.