web-dev-qa-db-ja.com

フラッター:ナビゲーターで新しい画面にプッシュするとき、BottomNavigationBarを維持

IOSには、 ITabBarController があります。これは、新しいViewControllerにプッシュすると、画面の下部に永続的に残ります。

Flutterには、ScaffoldのbottomNavigationBarがあります。ただし、iOSとは異なり、Navigator.Push新しい画面に移動すると、このbottomNavigationBarは消えます。

私のアプリでは、この要件を満たす必要があります:ホーム画面には、2つの項目(ab)が表示されたbottomNavigationBarがあります[〜#〜] a [〜#〜][〜#〜] b [〜#〜]。デフォルトでは、画面[〜#〜] a [〜#〜]が表示されます。画面内[〜#〜] a [〜#〜]には、ボタンがあります。そのボタンをタップ、Navigator.Pushスクリーンへ[〜#〜] c [〜#〜]。画面[〜#〜] c [〜#〜]では、bottomNavigationBarを引き続き見ることができます。アイテムbをタップし、画面に移動します[〜#〜] b [〜#〜]。画面[〜#〜] b [〜#〜]で、bottomNavigationBarの項目aをタップします。 screen[〜#〜] c [〜#〜](not[〜#〜] a [〜#〜][〜#〜] a [〜#〜]は現在以下です[〜#〜] c [〜#〜]inナビゲーション階層)。

これどうやってするの?みんなありがとう。

編集:デモンストレーション用のいくつかの写真を含めています:

画面A 画面A

をタップCボタン、画面Cにプッシュ 画面C

下のナビゲーションバー内の右アイテムをタップし、画面Bに移動します 画面B

8
kcatstack

tl; dr: CupertinoTabScaffoldCupertinoTabBar を使用

問題はFlutterではなく、RémiRousseletが述べたようにUXにあります。

マテリアルデザインでは、ボトムナビゲーションバーにアクセスするために階層内のサブページを推奨していません。

ただし、iOS Human Interface Guideはこれを推奨しています。そのため、この機能を使用するには、MaterialウィジェットではなくCupertinoウィジェットを適応させる必要がありました。特に、メインでは、WidgetsApp/MaterialAppにはCupertinoTabScaffoldが含まれます。 CupertinoTabBarを使用してタブバーを実装します。各画面はCupertinoTabViewです。

9
kcatstack

ルートを使用してMaterialAppを作成し、BottomNavigationBarをその兄弟にする必要があります。次に、BottomNavigationBarに渡すMaterialApp.navigatorKeyを使用してナビゲーションを行います。

https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5

7
robotoaster

あなたは実際に体内にプレースホルダーを置くことができるので、このような構造

- AppBar
- body (dynamic content from placeholder)
- BottomNavigationBar

次に、プレースホルダーとして別のクラスがあるので、BottomNavigationBarをタップするたびに、本文のコンテンツが更新されます

私が見つけた1つの例はこちらです https://willowtreeapps.com/ideas/how-to-use-flutter-to-build-an-app-with-bottom-navigation

そしてここでは、あまりにも複雑で私にとっては機能していません https://medium.com/@swav.kulinski/flutter-navigating-off-the-charts-e118562a36a5

そしてこれ https://medium.com/coding-with-flutter/flutter-case-study-multiple-navigators-with-bottomnavigationbar-90eb6caa6dbf

3
stuckedoverflow

これを行う正しい方法は、BottomNavigationBarを Hero で同じタグでラップすることだと思います。このように、ページ間のアニメーションが発生すると、それらは除外されます。

これは簡単な例ですが、クリーンアップすることを強くお勧めします。つまり、巨大なビルドブロックではなくウィジェットを使用してヒーロー文字列を渡し、BottomNavigationBarの独自のウィジェットを作成することを強くお勧めします。

ヒーローの移行中にoverflow by 0.0000191 pixels少なくとも私の電話では、リリースモードでは問題になりません。

import 'package:flutter/material.Dart';

void main() => runApp(new MaterialApp(
      home: new Builder(
        builder: (context) => new Scaffold(
              bottomNavigationBar: new Hero(
                tag: "bottomNavigationBar",
                child: new BottomNavigationBar(items: [
                  new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Home")),
                  new BottomNavigationBarItem(icon: new Icon(Icons.ac_unit), title: new Text("AC Unit"))
                ]),
              ),
              body: new SafeArea(
                child: new Container(
                  constraints: new BoxConstraints.expand(),
                  color: Colors.green,
                  child: new Column(
                    children: <Widget>[
                      new RaisedButton(
                          child: new Text("Press me"),
                          onPressed: () {
                            Navigator.Push(
                                context,
                                new MaterialPageRoute(
                                    builder: (context) => new Scaffold(
                                          bottomNavigationBar: new Hero(
                                            tag: "bottomNavigationBar",
                                            child: new BottomNavigationBar(items: [
                                              new BottomNavigationBarItem(icon: new Icon(Icons.home), title: new Text("Home")),
                                              new BottomNavigationBarItem(icon: new Icon(Icons.ac_unit), title: new Text("AC Unit"))
                                            ]),
                                          ),
                                          body: new SafeArea(
                                            child: new Container(
                                              constraints:
                                                  new BoxConstraints.expand(),
                                              color: Colors.red,
                                              child: new Column(
                                                children: <Widget>[
                                                  new RaisedButton(
                                                    onPressed: () =>
                                                        Navigator.pop(context),
                                                    child: new Text("Back"),
                                                  )
                                                ],
                                              ),
                                            ),
                                          ),
                                        )));
                          })
                    ],
                  ),
                ),
              ),
            ),
      ),
    ));

heroシステムが複数のヒーローなどをどれだけうまく処理できるかわかりません。ナビゲーションバーをアニメーション化する場合、これはうまく機能しない可能性があります。

これを行う別の方法があり、下部のナビゲーションバーをアニメーション化できます。それは実際にはすでに答えられた質問です: フラッター:ヒーローの移行+ウィジェットのアニメーション?

2
rmtmckenzie

これを実現する別の方法(良い方法ではありませんが)は、足場の本体にマテリアルアプリをネストすることです。そして、すべての「サブナビゲーション」をそこで処理します。

したがって、階層は次のようになります

Material App
  - home
     - Scaffold
       - body
         - Material App
              - Scaffold
                  - AppBar
                  - body
                  ...
         - routes (internal)
       - bottomNavigationBar
  - routes (external)

私はこれを試しましたが、完全に機能します。残念ながら、今はソースコードを投稿できません。

1

NavigatorウィジェットにStackウィジェットを作成して、タブの内部ナビゲーションでBottomNavigationBarを使用できます。 WillPopScopeを使用して、Androidの戻るボタンを処理し、タブの内部画面をポップすることができます。また、下部のナビゲーション項目をダブルタップして、タブのすべての内部画面をポップします。

このために サンプルアプリ を作成しました。

この助けを願っています!

0
Hemant Kaushik

その効果を実現する、小さくて非常に使いやすいパッケージを作成しました CustomNavigator そして、それについてのチュートリアルを、Mediumで見つけました here

0
Ayham Orfali