美文网首页
Flutter路由跳转参数处理小技巧

Flutter路由跳转参数处理小技巧

作者: 一笑轮回吧 | 来源:发表于2023-07-30 18:16 被阅读0次

    需求

    我们在开发应用中,经常会出现一个界面跳转到另外一个界面并带有参数传递,在Android中大家都知道使用Intent传递参数,在第二个Activity中onCreate中可以获取到这个参数。

    实现

    那么在Flutter中,我们经常会使用路由跳转到另外一个界面,那么如果这个时候需要传参。 代码如下:

    /// 路由跳转并带参数
     Navigator.pushNamed(
                context,
                RouteConst.routeNext,
                arguments: (TestArguments("一笑轮回", "江苏省徐州市")),
    );       
    
    /// 测试数据模型
    class TestArguments {
      String? name;
      String? address;
      TestArguments(this.name, this.address);
    }
    

    没错,直接赋值arguments字段就可以了,那么我们如何获取呢?

    在第二个页面中

    class TwoPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        // 从路由设置中获取传递的参数
        var arguments = ModalRoute.of(context)?.settings.arguments;
        // 其他部分的代码...
      }
    }
    

    我们需要通过 ModalRoute.of(context)?.settings.arguments获取数据,那么我们直接在 initState方法中直接通过 ModalRoute.of(context)?.settings.arguments获取,会报错

    image.png

    这里出错原因,可以通过错误并查看源码可知,这里部讲述。

    我们有的时候需要在initState方法中获取数据并处理一些事情,我们应该怎么做呢?

    下面提供一个小技巧。

    • 路由定义
    class RouteConst {
      static const routeNext = "/route_next";
    }
    
    class RoutePathConst {
      static var routePaths = <String, Widget Function(BuildContext context)>{
        RouteConst.routeNext: (context) => ArgumentsNextPage(),
      };
    }
    
    • 跳转代码
    Navigator.pushNamed(
                context,
                RouteConst.routeNext,
                arguments: (TestArguments("一笑轮回", "江苏省徐州市")),
              );
    
    /// 测试数据模型
    class TestArguments {
      String? name;
      String? address;
    
      TestArguments(this.name, this.address);
    }
    
    • 定义ArgumentsMixin
    /// Arguments参数数据
    mixin ArgumentsMixin {
      late final Object? arguments;
    }
    
    /// 路由拼接的参数数据
    mixin RouteQueryMixin {
      final Map<String, String> routeParams = HashMap();
    }
    
    • 重写onGenerateRoute
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          ...
          onGenerateRoute: (settings) {
            var uri = Uri.parse(settings.name ?? "");
            var route = uri.path;
            var params = uri.queryParameters;
            if (!RoutePathConst.routePaths.containsKey(route)) {
              return null;
            }
            return MaterialPageRoute(
              builder: (context) {
                var widgetBuilder = RoutePathConst.routePaths[route];
                var widget = widgetBuilder!(context);
                if (widget is RouteQueryMixin) {
                  (widget as RouteQueryMixin).routeParams.addAll(params);
                }
                if (widget is ArgumentsMixin) {
                  (widget as ArgumentsMixin).arguments = settings.arguments;
                }
                return widget;
              },
              settings: settings,
            );
          },
        );
      }
    }
    
    • 创建ArgumentsNextPage
    ///第二页
    class ArgumentsNextPage extends StatefulWidget
        with ArgumentsMixin, RouteQueryMixin {
      ArgumentsNextPage({super.key});
    
      @override
      State<ArgumentsNextPage> createState() => _ArgumentsNextPageState();
    }
    
    class _ArgumentsNextPageState extends State<ArgumentsNextPage> {
      /// 传参数据文本
      String get result {
        // Arguments传参数据
        TestArguments? arguments;
        if (widget.arguments != null && widget.arguments is TestArguments) {
          arguments = widget.arguments as TestArguments;
        }
    
        // 路由拼接的数据
        var params = widget.routeParams;
    
        // 拼接结果数据
        return "arguments:name=${arguments?.name ?? ""} address=${arguments?.address ?? ""} \nrouteParams=$params";
      }
    
      @override
      void initState() {
        super.initState();
        print("result=$result}");
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: XYAppBar(
            title: "第二页",
            onBack: () {
              Navigator.pop(context);
            },
          ),
          body: Center(
            child: Text(result),
          ),
        );
      }
    }
    

    这样就OK了,好像没讲啥,直接看代码吧。

    相关文章

      网友评论

          本文标题:Flutter路由跳转参数处理小技巧

          本文链接:https://www.haomeiwen.com/subject/ntmspdtx.html