Flutter FCM导航 onResume/onLaunch

huangapple go评论76阅读模式
英文:

Flutter FCM Navigation onResume/onLaunch

问题

在我的应用程序中,我有一个名为“home”的类,用户在授权后导航到该类。在“home”中,有一个带有BottomNavigationBar的PageView。当用户从Firebase收到推送通知(新消息)时,他应该在点击后导航到特定的聊天ChatHome和特定的聊天界面。我该如何做到这一点?

ChatHome看起来像这样:

@override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: PageView(
        children: <Widget>[
          Feed(userID: widget.userID),
          SearchView(),
          ChatHome(),
          Profile(
              uid: currentUser?.uid,
              auth: widget.auth,
              logoutCallback: widget.logoutCallback,
          ),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
          currentIndex: pageIndex,
          inactiveColor: Colors.white,
          backgroundColor: Color.fromRGBO(0, 111, 123, 1),
          activeColor: Color.fromRGBO(251, 174, 23, 1),
          onTap: onTap,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home, size: 20),
              title: Text("Home"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search, size: 20),
              title: Text("Search"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.chat, size: 20),
              title: Text("Chats"),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.profile, size: 20),
              title: Text("Profile"),
            ),
          ]),
    );
  }

在ChatHome中,我有一个ListTiles,显示了所有聊天伙伴。用户点击后会导航到特定的聊天。

Navigator.push(
    context,
    MaterialPageRoute(
        builder: (context) => Chat(
            chatPartnerId: chatPartner[index].uid,
            chatPartnerName: chatPartner[index].username,
            chatPartnerPhotoUrl: chatPartner[index].photoUrl)));

在主页中,我有我的onResume方法。

我尝试了不同的方法,但找不到好的解决方案。

以下代码,我能够导航到ChatHome,但BottomNavigationBar消失了。

onResume: (Map<String, dynamic> message) async {
    final screen = message['screen'];
    print(screen);
    if(screen == "ChatHome"){
        Navigator.pushNamed(context, '/chatHome');
    } 
},

以下代码不起作用,因为应用程序跳来跳去,最终回到主页。

onResume: (Map<String, dynamic> message) async {
    final screen = message['screen'];
    print(screen);
    if(screen == "ChatHome"){
        Navigator.pushNamed(context, '/home').then((_) => pageController.jumpToPage(2));
    } 
},

路由设置如下:

routes: {
    '/rootPage': (BuildContext context) => new RootPage(auth: new Auth()),
    '/chatHome': (BuildContext context) => ChatHome(),
    '/home': (BuildContext context) => Home(),
},

希望对您有所帮助。

英文:

In my app, I got a class "home" where the user is navigated to after he is authorized. Within "home" there is a PageView with BottomNavigationBar. When the user is getting a push notification from firebase (new message) he should be navigated to ChatHome and to the specific chat after tapping. How can I do this?

Home does look like this

@override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      body: PageView(
        children: &lt;Widget&gt;[
          Feed(userID: widget.userID),
          SearchView(),
          ChatHome(),
          Profile(
              uid: currentUser?.uid,
              auth: widget.auth,
              logoutCallback: widget.logoutCallback,
          ),
        ],
        controller: pageController,
        onPageChanged: onPageChanged,
        physics: NeverScrollableScrollPhysics(),
      ),
      bottomNavigationBar: CupertinoTabBar(
          currentIndex: pageIndex,
          inactiveColor: Colors.white,
          backgroundColor: Color.fromRGBO(0, 111, 123, 1),
          activeColor: Color.fromRGBO(251, 174, 23, 1),
          onTap: onTap,
          items: [
            BottomNavigationBarItem(
              icon: Icon(Icons.home, size: 20),
              title: Text(&quot;Home&quot;),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.search, size: 20),
              title: Text(&quot;Search&quot;),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.chat, size: 20),
              title: Text(&quot;Chats&quot;),
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.profile, size: 20),
              title: Text(&quot;Profile&quot;),
            ),
          ]),
    );
  }

In ChatHome I got ListTiles with all the chat partners. On click the user is navigated to the specific chat.

Navigator.push(
            context,
            MaterialPageRoute(
                builder: (context) =&gt; Chat(
                    chatPartnerId: chatPartner[index].uid,
                    chatPartnerName: chatPartner[index].username,
                    chatPartnerPhotoUrl: chatPartner[index].photoUrl)));

In home page, I got my onResume

I tried different things but could find a good solution

With the following code, I was able to navigate to ChatHome but the BottomNavigationBar disappeared.

onResume: (Map&lt;String, dynamic&gt; message) async {
          final screen = message[&#39;screen&#39;];
          print(screen);
          if(screen == &quot;ChatHome&quot;){
          Navigator.pushNamed(context, &#39;/chatHome&#39;);
        } 
      },

The following code didn't work well as the app jumped around and always ends in home.

onResume: (Map&lt;String, dynamic&gt; message) async {
          final screen = message[&#39;screen&#39;];
          print(screen);
          if(screen == &quot;ChatHome&quot;){
          Navigator.pushNamed(context, &#39;/home&#39;).then((_) =&gt; pageController.jumpToPage(2));
        } 
      },
routes: {
          &#39;/rootPage&#39;: (BuildContext context) =&gt; new RootPage(auth: new Auth()),
          &#39;/chatHome&#39;: (BuildContext context) =&gt; ChatHome(),
          &#39;/home&#39;: (BuildContext context) =&gt; Home(),
        },


Any help is appreciated.

答案1

得分: 1

你需要为你的MaterialApp小部件提供一个navigatorKey:

final GlobalKey<NavigatorState> navigatorKey = new GlobalKey<NavigatorState>();

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            ....
            navigatorKey: navigatorKey,
            ......
        );
    }
}

然后,你可以在onResume处理程序中使用这个navigatorKey进行导航:

onResume: (message) async {
    navigatorKey.currentState.pushNamed("/sample-route/" + message["data"]["..."])
}

对于onLaunch处理程序(它直接在启动时调用,意味着第一个应用程序视图尚未构建,因此不能立即使用navigatorKey),我只找到了一种“不太干净”的解决方案:

onLaunch: (message) async {
    Timer.periodic(
        Duration(milliseconds: 500),
        (timer) {
            if (navigatorKey.currentState == null) return;
            navigatorKey.currentState.pushNamed("/sample-route/" + message["data"]["..."]);
            timer.cancel();
        },
    );
}

当然,对于onLaunch的解决方案并不完美,但它可以工作。

英文:

You need to provide a navigatorKey to your MaterialApp Widget:

final GlobalKey&lt;NavigatorState&gt; navigatorKey = new GlobalKey&lt;NavigatorState&gt;();

class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            ....
            navigatorKey: navigatorKey,
            .....
        );
    }
}

Then, you can use this navigatorKey to navigate in your onResume handler:

onResume: (message) async {
    navigatorKey.currentState.pushNamed(&quot;/sample-route/&quot; + message[&quot;data&quot;][&quot;...&quot;])
}

For the onLaunch handler (which is called directly onLaunch, means the first app view isn't built yet which means you cannot use the navigatorKey instantly, I only found a hacky solution:

onLaunch: (message) async {
    Timer.periodic(
        Duration(milliseconds: 500),
        (timer) {
            if (navigatorKey.currentState == null) return;
            navigatorKey.currentState.pushNamed(&quot;/sample-route/&quot; + message[&quot;data&quot;][&quot;...&quot;]);
            timer.cancel();
        },
    );
}

Of course, the solution for onLaunch isn't clean, but it works.

huangapple
  • 本文由 发表于 2020年1月3日 23:55:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/59581554.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定