如何在Flutter应用程序中保存上次打开的屏幕

我试图在引导后重新打开上次打开的屏幕,是否有任何简单的方法?欢迎提供示例代码!

到目前为止,我尝试使用编写了一个代码(到某处)SharedPreferences,但是它不起作用。

import 'package:flutter/material.dart';

import 'package:shared_preferences/shared_preferences.dart';

String lastRouteKey = 'last_route';

void main() async {

SharedPreferences preferences = await SharedPreferences.getInstance();

String lastRoute = preferences.getString(lastRouteKey);

runApp(MyApp(lastRoute));

}

class MyApp extends StatelessWidget {

final String lastRoute;

MyApp(this.lastRoute);

@override

Widget build(BuildContext context) {

bool hasLastRoute = getWidgetByRouteName(lastRoute) != null;

return MaterialApp(

home: Foo(),

initialRoute: hasLastRoute ? lastRoute : '/',

onGenerateRoute: (RouteSettings route) {

persistLastRoute(route.name);

return MaterialPageRoute(

builder: (context) => getWidgetByRouteName(route.name),

);

},

);

}

Widget getWidgetByRouteName(String routeName) {

switch (routeName) {

case '/':

return MainWidget();

case '/':

return SecondRoute();

// Put all your routes here.

default:

return null;

}

}

void persistLastRoute(String routeName) async {

SharedPreferences preferences = await SharedPreferences.getInstance();

preferences.setString(lastRouteKey, routeName);

}

}

class Foo extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text('Foo'),

),

body: Column(

children: <Widget>[

RaisedButton(

child: Text('Open route second'),

onPressed: () {

Navigator.push(

context,

MaterialPageRoute(builder: (context) => SecondRoute()),

);

},

),

RaisedButton(

child: Text('Open route main'),

onPressed: () {

Navigator.push(

context,

MaterialPageRoute(builder: (context) => MainWidget()),

);

},

),

],

),

);

}

}

class SecondRoute extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text("Second Route"),

),

body: Center(

child: RaisedButton(

onPressed: () {

Navigator.pop(context);

},

child: Text('Go back!'),

),

),

);

}

}

class MainWidget extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Scaffold(

appBar: AppBar(

title: Text("MainWidget"),

),

body: Center(

child: RaisedButton(

onPressed: () {

Navigator.pop(context);

},

child: Text('Go back!'),

),

),

);

}

}

我应该使用SQLiteJSON代替SharedPreferences,使代码简单?谢谢。

回答:

回答:

实际上,当我们在应用程序中的不同屏幕之间导航时,路线堆栈正在发生变化。

因此,首先,我们需要弄清楚如何收听此更改,例如“推送”屏幕,“弹出回到用户”屏幕。

我们实际上可以将其放在每个与导航相关的按钮上。

一个。抽屉物品

  ListTile(

title: Text("Beta"),

onTap: () {

saveLastScreen(); // saving to SharedPref here

Navigator.of(context).pushNamed('/beta'); // then push

},

),

    appBar: AppBar(

title: Text("Screen"),

leading: IconButton(

icon: Icon(Icons.menu),

onPressed: () {

saveLastScreen(); // saving to SharedPref here

Navigator.pop(context); // then pop

},

),

),

  @override

Widget build(BuildContext context) {

return WillPopScope(

onWillPop: (){ // will triggered as we click back button

saveLastScreen(); // saving to SharedPref here

return Future.value(true);

},

child: Scaffold(

appBar: AppBar(

title: Text("Base Screen"),

),

因此,我们将拥有更多的代码,并且将更加难以管理。

2. 使用以下方法收听路线更改 Route observer

尽管如此,Flutter在MaterialApp上提供了一些“ middleware”来捕获路径堆栈中的那些更改。

我们的MyApp小部件上可能有这个:

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

title: 'Save Last Route',

navigatorObservers: <NavigatorObserver>[

MyRouteObserver(), // this will listen all changes

],

routes: {

'/': (context) {

return BaseScreen();

},

'/alpha': (context) {

return ScreenAlpha();

},

我们可以定义MyRouteObserver类如下:

class MyRouteObserver extends RouteObserver {

void saveLastRoute(Route lastRoute) async {

final SharedPreferences prefs = await SharedPreferences.getInstance();

prefs.setString('last_route', lastRoute.settings.name);

}

@override

void didPop(Route route, Route previousRoute) {

saveLastRoute(previousRoute); // note : take route name in stacks below

super.didPop(route, previousRoute);

}

@override

void didPush(Route route, Route previousRoute) {

saveLastRoute(route); // note : take new route name that just pushed

super.didPush(route, previousRoute);

}

@override

void didRemove(Route route, Route previousRoute) {

saveLastRoute(route);

super.didRemove(route, previousRoute);

}

@override

void didReplace({Route newRoute, Route oldRoute}) {

saveLastRoute(newRoute);

super.didReplace(newRoute: newRoute, oldRoute: oldRoute);

}

}

回答:

当用户通过屏幕进行交互时,共享首选项将始终

存储最后的路线名称。为了使应用程序进行相应的导航,我们需要

使BaseScreen statefull并覆盖其initState方法,如下所示:

return MaterialApp(

routes: {

'/': (context) {

return BaseScreen(); // define it as Main Route

},

class BaseScreen extends StatefulWidget {

@override

_BaseScreenState createState() => _BaseScreenState();

}

class _BaseScreenState extends State<BaseScreen> {

@override

void initState() {

super.initState();

navigateToLastPage();

}

void navigateToLastPage() async {

final SharedPreferences prefs = await SharedPreferences.getInstance();

String lastRoute = prefs.getString('last_route');

// No need to push to another screen, if the last route was root

if (lastRoute.isNotEmpty && lastRoute != '/') {

Navigator.of(context).pushNamed(lastRoute);

}

}

C.工作仓库您可能会看到该存储库覆盖了RouteObserver,如上面第二个选项所述

在不同的开始中保存和打开Screen Beta和Screen Delta

回答:

为了简化起见,我建议使用“共享”首选项。由于我们只记录了

简单的String作为路由名称,因此我们只能将两行代码保存到Save中,将

两行代码写入Load。

如果使用JSON文件,则需要使用path_providerpackage 为其手动设置Path 。

此外,如果使用SQLite,则需要设置数据库(可能包括多于8行),设置表以及插入表的方法。

以上是 如何在Flutter应用程序中保存上次打开的屏幕 的全部内容, 来源链接: utcz.com/qa/411337.html

回到顶部