Flutter menghapus semua rute

98

Saya ingin mengembangkan tombol logout yang akan mengirim saya ke rute masuk dan menghapus semua rute lain dari Navigator. Dokumentasi tampaknya tidak menjelaskan cara membuat RoutePredicateatau memiliki fungsi removeAll apa pun.

chrislondon.dll
sumber

Jawaban:

267

Saya dapat melakukannya dengan kode berikut:

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

Rahasianya di sini adalah menggunakan RoutePredicate yang selalu mengembalikan false (Route<dynamic> route) => false. Dalam situasi ini, ini menghapus semua rute kecuali untuk /loginrute baru yang saya dorong.

chrislondon.dll
sumber
1
Terima kasih banyak, ini berhasil. Bisakah Anda mengirim beberapa tautan, di mana saya dapat memahami lebih lanjut ....
Pawan
Saya punya masalah dengan ini! Di iOS, dengan menggunakan tampilan asli sebagai widget, setelah menggunakan metode Anda, tampilan asli tidak dibuang dengan benar dan terus ada, akibatnya saya memiliki tampilan yang tidak akan pernah digunakan lagi berjalan di semacam latar belakang dan tidak mungkin untuk dibuang . Ini sepertinya terjadi hanya di perangkat iOS.
Lorenzo Imperatrice
@LorenzoImperatrice Apakah Anda menemukan perbaikan untuk masalah ini? Saya mengalami masalah serupa
Mateusz Tylman
3
Saya masih memiliki instance yang terbuka bahkan setelah menggunakan ini. ada solusi lain untuk mendorong layar dan menghapus sisa tumpukan?
Manoj MM
Bagaimana kita bisa menyampaikan argumen dengan pendekatan ini.
Developine
78

saya dapat melakukannya dengan potongan kode berikut:

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

jika Anda ingin menghapus semua rute di bawah rute yang didorong, RoutePredicate selalu mengembalikan false , misalnya (Route route) => false .

amir khan
sumber
24

Alternatif lainnya adalah popUntil()

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

Ini akan menghentikan semua rute sampai Anda kembali ke rute yang ditentukan.

nleslie.dll
sumber
1
Saya lebih suka jawaban ini!
novel bahkan
10

Jika Anda ingin kembali ke layar tertentu dan Anda tidak menggunakan router bernama dapat menggunakan pendekatan selanjutnya

Contoh:

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

Dengan rute adalah HomePage Anda memeriksa nama widget Anda.

Volodymyr Bilovus
sumber
apa itu NoAnimatedRoute? Tidak dapat menemukan kelas dengan nama seperti itu di Flutter
kashlo
@ kashlo Don't pay attention =) Ini hanya implementasi saya yang dapat menggunakan MaterialPageRoute sebagai gantinya. Tapi saya sudah mengedit jawabannya, terima kasih.
Volodymyr Bilovus
(Rute <dynamic> rute) => rute.isFirst) Jika beberapa ingin menghapus sampai rute pertama.
Hussnain Haidar
4

Jika Anda menggunakan namesRoutes, Anda dapat melakukannya dengan:

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

Di mana "/ login" adalah rute yang ingin Anda dorong di tumpukan rute.

Perhatikan Bahwa:

Pernyataan ini menghapus semua rute dalam tumpukan dan membuat yang didorong menjadi root.

Kelvin Mboto
sumber
3

Saya tidak tahu mengapa tidak ada yang menyebutkan solusi menggunakan SchedularBindingInstance , Agak terlambat ke pesta, saya pikir ini akan menjadi cara yang tepat untuk melakukannya awalnya dijawab di sini

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

Kode di atas menghapus semua rute dan navigasi ke '/ login' ini juga memastikan bahwa semua frame dirender sebelum menavigasi ke rute baru dengan menjadwalkan panggilan balik

maheshmnj.dll
sumber
1

Ini bekerja untuk saya. Sebenarnya, saya bekerja dengan blok tetapi masalah saya adalah blok layar masuk. Itu tidak diperbarui setelah logout. Itu memegang data model sebelumnya. Bahkan, saya memasukkan entri yang salah. Itu akan ke Layar Beranda.

Langkah 1:

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

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

Langkah 2:

Ini berfungsi untuk menyegarkan layar. Jika Anda bekerja dengan Bloc maka itu akan sangat membantu.

runApp(MyApp());

dimana, MyApp() is the root class.

Kode kelas root (yaitu 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());

Berikut adalah metode Logout Saya ,

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

Tidak yakin apakah saya melakukan ini dengan benar

tapi ini sesuai dengan kasus penggunaan saya untuk popping sampai dengan widget root

void popUntilRoot({Object result}) {
    if (Navigator.of(context).canPop()) {
      pop();
      popUntilRoot();
    }
}
Vinesh Raju
sumber
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);
}
sj
sumber