【问题标题】:How to pass in arguments in flutter when user input URL address (using auto_route)用户输入URL地址时如何在flutter中传递参数(使用auto_route)
【发布时间】:2021-06-13 08:33:40
【问题描述】:

我的应用程序使用带有 auto_router 0.6.9 包的 Flutter,我希望 用户能够输入网址 http://localhost/#/book/123 并能够访问 book 123 并显示book123、他们的姓名和电子邮件(如果他们已登录)。我已经用 auto_router 弄清楚了路由部分,但是当用户直接将地址输入浏览器时,应该将参数传递到页面中。

我想知道有没有办法在显示页面之前解析 url 并传入所需的参数。感谢您的帮助或提示!

我的 router.dart 页面:

@MaterialAutoRouter(
  routes: <AutoRoute>[
    // some other pages...
    MaterialRoute(path: "/book/:id", page: MultiProvider),
  ],
)
class $ModularRouter {}

为多提供者参数类生成的 router.gr.dart 是:

/// MultiProvider arguments holder class
class MultiProviderArguments {
  final Key key;
  final List<SingleChildWidget> providers;
  final Widget child;
  final Widget Function(BuildContext, Widget) builder;
  MultiProviderArguments(
      {this.key, @required this.providers, this.child, this.builder});
}

我的图书菜单页面包含导航:
(这是我通常如何在另一个页面中调用 BookPage 的示例)

child: GestureDetector(
onTap: () => ExtendedNavigator.of(context).push(
    Routes.multiProvider(id: book[index].bookID),
    arguments: MultiProviderArguments(
    providers: [
        Provider<UserData>.value(
            value: userdata,
        ),
        Provider<List<BookInfo>>.value(
            value: book,
        ),
    ],
    child: BookPage(
        bookId: book[index].bookID,
        name: userdata.userName,
        email: userdata.email,
    ),
    ),
),
...

BookPage 接受 3 个参数 bookId、name 和 email:

class BookPage extends StatefulWidget {
  final String bookId;
  final String name;
  final String email;

  BookPage({
    this.bookId,
    this.name,
    this.email,
  });
...
}

...

class _BookPageState extends State<BookPage> {
    ...
    Widget build(BuildContext context) {
        final currentUser = Provider.of<UserData>(context, listen: false);
        final currentBook = Provider.of<List<BookInfo>>(context, listen: false);
        ...
    }
}

【问题讨论】:

    标签: flutter dart routes


    【解决方案1】:

    我想出了一个创可贴解决方案(我认为这不是永久性的):

    我已经放弃使用自动路由,但我不知道如何解析 url 并改用 onGenerateRoute:

    onGenerateRoute: (settings) {
      final settingsUri = Uri.parse(settings.name);
      final user = Provider.of<User>(context);
    
      if (user == null) {
        return MaterialPageRoute(
            builder: (context) {
              return LogInPage();
            }
        );
      } else {
        // Handle '/'
        if (settingsUri.pathSegments.length == 0) {
          return MaterialPageRoute(
              builder: (context) {
                return PageWrapper(false, bookid);
              }
          );
        }
    
        // Handle '/book/:id'
        if (settingsUri.pathSegments.length == 2) {
          if (settingsUri.pathSegments.first != 'book') {
            return MaterialPageRoute(
                builder: (context) {
                  return UnknownPage();
                }
            );
          }
    
          final bookid = settingsUri.pathSegments.elementAt(1);
          if (bookid == null) {
            return MaterialPageRoute(
              builder: (context) {
                return UnknownPage();
              }
            );
          }
    
          return MaterialPageRoute(
              builder: (context) {
                return PageWrapper(false, bookid);
              }
          );
        }
      }
      //Handle other unknown Routes
      return MaterialPageRoute(
          builder: (context) {
            return UnknownPage();
          }
      );
    }
    

    PageWrapper 对用户进行身份验证,构建提供者,并调用 BookPage 类,我将代码放在 userData 提供者已经初始化的地方:

    if (this.needRedirect == true) {
      return Scaffold(
        ...
        body: FutureBuilder(
            future: Future.wait([userData]),
            builder: (context, snapshot) {
              return MultiProvider(
                  providers: [
                    //initialize using streamproviders
                    ...
                  ],
                  child: BookPage(
                    bookId: book[index].bookID,
                    name: userdata.userName,
                    email: userdata.email,
                  ),
              );
            }),
      );
    }
    else {...}
    

    简短的回答是我在 onGenerateRoutes 中调用了 WrapperPage,因为提供程序没有在 main.dart 中初始化,而是在 WrapperPage 中初始化。然后我将提供程序初始化后的重定向代码放在 WrapperPage 中并调用 BookPage。

    这个方法引起了其他错误,但它已经达到了它的目的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-24
      • 1970-01-01
      • 2010-09-13
      相关资源
      最近更新 更多