【ポップ】フラッタ学ぶヒントと(スナックバー、BottomSheet、ダイアログ)の基本的な構成要素

I.概要  

  Flutter操作のヒントは非常に少ないがある  SnackBarので、 BottomSheet より多くのスタイル、そして最終的にはうまく話す置きますDialogDialog

第二に、導入

  • スナックバー

    スナックバーのソースコードは比較的簡単です

    • コンストラクタ
      CONST スナックバー({
          キー、キー、
          @required この .contentを、// プロンプト
          この .backgroundColor、// の背景色
          この .actionを、// スナックバーテールボタンロールバック操作のいくつかのために
          、この .duration = _kSnackBarDisplayDuration、// 彼らが滞在する時間を、デフォルトの4000ms 
          この .animation、// アウトアニメーション 
        })
    • 例デモ
        ユーザープロンプト我々は、操作を元に戻すためにユーザーがボタンを与えている間、それができる、修正、値を変更する機能を実装する必要がある場合は  SnackBar簡単に実現すること。
      ある  SnackBar缶と  floatingActionButton完璧なフィット感をするとき、ポップアップをブロックしていません、 fab
      クラス _PromptDemoPageStateが伸長状態<PromptDemoPage> {
         VARのカウント= 0 ;
      
        @オーバーライド
        ボイドinitState(){
          super.initState();
        }
      
        @オーバーライド
        ボイド廃棄(){
          super.dispose();
        }
      
        // インクリメントオペレータ
        増加(){
          SETSTATE(() =>カウント++ );
        }
      
        // デクリメント演算
        減少(){
          SETSTATE(() => count-- )。
        }
      
        _changeValue(BuildContextコンテキスト){
          増加する();
          Scaffold.of(コンテキスト).showSnackBar(スナックバー(
              コンテンツ:テキスト(現在の値が変更されています" )、
              アクション:SnackBarAction(ラベル:' 撤销' 、onPressed:減)、
              期間:所要時間(ミリ秒:2000 )));
        }
      
        @オーバーライド
        ウィジェットビルド(BuildContextコンテキスト){
          リターン足場(
            アプリケーションバー:アプリケーションバー(
              タイトル:テキスト(プロンプトデモ)、
            )、
            ボディ:カラム(子供: <ウィジェット> [
              テキスト(' 現在の値:$のCOUNT '、スタイル:TEXTSTYLE(のfontSize:20.0 ))、
              拡張(
                // 拡張を容易にするために、抽出法`snackBar`、そして上のボタンのリストの私の側 
                子供:リストビュー(
      パディング:CONST EdgeInsets.symmetric(水平:12.0、の垂直数:8.0)、
         子供:<ウィジェット> [ / / コンテキストを提供する必要性を備えるスナックバー、コンテキストではなく、コンテキスト足場ノードで、ビルダーの層ラップする必要があり ビルダー(ビルダー:(文脈)= > RaisedButton(onPressed:()=> _changeValue(コンテキスト)、子供を:テキスト' 現在の値を変更します' )))、 ])) ])、 // ときスナックバーポップ、いくつかの距離で、ファブシフト floatingActionButton:ビルダー( ビルダー:(文脈) => FloatingActionButton(onPressed:()=> _changeValue(コンテキスト)、子供:アイコン(Icons.send)))、 ); } }
    • レンダリングは
      探してください  fab変更と値:
  • BottomSheet

      BottomSheetは、これが示す、下部にあるポップアップメニューから、名前であることがわかりBottomSheetを二つの方法、すなわちでshowBottomSheetshowModalBottomSheet方法は何の違いを呼び出していない、タイプの違いを示すための唯一の二つの方法が、showBottomSheetFAB、アニメーションの組み合わせがあるshowModalBottomSheetいや、それの実用的な例を見てください。では、リストビューの増加BottomSheetのためのボタン、BottomSheetが必要なコンテキストをすることができない足場コンテキスト、それはによって必要なBuilderのラッピング層、そして追加_showBottomSheetの方法を
    • 方法の例  
      _showBottomSheet(BuildContextコンテキスト){
       showBottomSheet(
        コンテキスト:コンテキスト、
        ビルダー:(コンテキスト) => リストビュー(
         // 生成するリスト・セレクタ
        子供:List.generate(20は
      (指数)
      => インクウェル(
      子:コンテナ(
      アラインメント:Alignment.center、
      高さ:
      60.0
      子供:テキスト(' + $ {インデックス1項} ' ))、 ONTAP:(){ プリント(' タップアイテム$ {指数+ 1} ' ); Navigator.pop(コンテキスト)。 } // ONTAP
      )、//コンテナ )//インク入れ
      )、//生成 );//リストビュー }

      showBottomSheetは交換しshowModalBottomSheetは内部が何らかの変更を加える必要はありません表示する別の方法です。

    • 業績
      私たちは二つの実験の効果を見てみましょう。
    • 拡張は
      見ることができますshowBottomSheetは、画面全体を埋め、次に続く製造工場に行ってきましたでしょうアプリケーションバーながら、下の位置をshowModalBottomSheetは、高さが画面の半分の高さを超えるのではなく、表示さファブその隠さによって。我々は唯一の2-3表示する必要がある場合は項目を、しかし方法で、ちょうどshowModalBottomSheet高さが高すぎる、我々はできるのListView小包の外層コンテナをした後、指定した高さにします
      _showModalBottomSheet(BuildContextコンテキスト){
          (モーダルボトムシートを表示
            コンテキスト:コンテキスト、
            ビルダー:(文脈) => コンテナ(
                  子供:リストビュー(
                      子供:List.generate(
                    2 
                    (指数) => インクつぼ(
                        子:コンテナ(アラインメント:Alignment.center、高さ:60.0、子:テキスト(' アイテム$ {指数+ 1} ' ))、
                        ONTAP:(){
                          プリント(' タップアイテム$ {指数+ 1} ' );
                          Navigator.pop(コンテキスト)。
                        })、
                  ))、
                  高さ:120 
                )、
          );
        }
      • 高さを変更する効果
  • ダイアログ

      相对于 SnackBarBottomSheetDialog的使用场景相对会更多,在 MaterialDesign下,
          Dialog主要有 3 种:AlertDialogSimpleDialogAboutDialog,当然在 Cupertino风格下也有相应的 Dialog,因为这个系列以 MaterialDesign风格为主,所以
          Cupertiono等下次有时间再写吧。
    • AlertDialog

        在 ListView中增加一个 AlertDialog的按钮,用于点击显示 AlertDialog用,然后加入显示 AlertDilaog的方法,并将按钮的 onPressed指向该方法,Dialogcontext可以是 Scaffold下的 context,所以不需要用 Builder来包裹一层。
      • 示例代码
        _showAlertDialog() {
            showDialog(
                // 设置点击 dialog 外部不取消 dialog,默认能够取消
                barrierDismissible: false,
                context: context,
                builder: (context) => AlertDialog(
                      title: Text('我是个标题...嗯,标题..'),
                      titleTextStyle: TextStyle(color: Colors.purple), // 标题文字样式
                      content: Text(r'我是内容\(^o^)/~, 我是内容\(^o^)/~, 我是内容\(^o^)/~'),
                      contentTextStyle: TextStyle(color: Colors.green), // 内容文字样式
                      backgroundColor: CupertinoColors.white,
                      elevation: 8.0, // 投影的阴影高度
                      semanticLabel: 'Label', // 这个用于无障碍下弹出 dialog 的提示
                      shape: Border.all(),
                      // dialog 的操作按钮,actions 的个数尽量控制不要过多,否则会溢出 `Overflow`
                      actions: <Widget>[
                        // 点击增加显示的值
                        FlatButton(onPressed: increase, child: Text('点我增加')),
                        // 点击减少显示的值
                        FlatButton(onPressed: decrease, child: Text('点我减少')),
                        // 点击关闭 dialog,需要通过 Navigator 进行操作
                        FlatButton(onPressed: () => Navigator.pop(context), 
                                   child: Text('你点我试试.')),
                      ],
                    ));
          }

         

      • 效果

    • SimpleDialog

      SimpleDialog相比于 AlertDialog少了 contentaction参数,多了 children属性,需要传入 Widget列表,那就可以自定义全部内容了。那我们这里就实现一个性别选择的 Dialog,选择后通过 Taost提示选择的内容,Taost就是之前导入的第三方插件,只要实现 children 是个列表选择器就可以了。

      • 示例代码
        _showSimpleDialog() {
            showDialog(
                barrierDismissible: false,
                context: context,
                builder: (context) => SimpleDialog(
                      title: Text('我是个比较正经的标题...\n选择你的性别'),
                      // 这里传入一个选择器列表即可
                      children: _genders
                          .map((gender) => InkWell(
                                child: Container(height: 40.0, child: Text(gender), alignment: Alignment.center),
                                onTap: () {
                                  Navigator.pop(context);
                                  Fluttertoast.showToast(msg: '你选择的性别是 $gender');
                                },
                              ))
                          .toList(),
                    ));
          }

         

      • 效果

 

 

    • AboutDialog

      AboutDialog主要是用于展示你的 App或者别的相关东西的内容信息的,平时用的比较少,显示 AboutDialog有两种方式可以展示,一种是前面一样的 showDialog方法,传入一个 AboutDialog实例,还有中方法是直接调用 showAboutDialog方法。我们还是一样在列表加个按钮,并指向显示 AboutDialog的事件。
      • 示例代码
        _showAboutDialog() {
            showDialog(
                barrierDismissible: false,
                context: context,
                builder: (context) => AboutDialog(
                      // App 的名字
                      applicationName: 'Flutter 入门指北',
                      // App 的版本号
                      applicationVersion: '0.1.1',
                      // App 基本信息下面会显示一行小字,主要用来显示版权信息
                      applicationLegalese: 'Copyright: this is a copyright notice topically',
                      // App 的图标
                      applicationIcon: Icon(Icons.android, size: 28.0, color: CupertinoColors.activeBlue),
                      // 任何你想展示的
                      children: <Widget>[Text('我是个比较正经的对话框内容...你可以随便把我替换成任何部件,只要你喜欢(*^▽^*)')],
                    ));
          }

        也可以通过 showAboutDialog实现同样的效果

          _showAboutDialog() {
            showAboutDialog(
              context: context,
              applicationName: 'Flutter 入门指北',
              applicationVersion: '0.1.1',
              applicationLegalese: 'Copyright: this is a copyright notice topically',
              applicationIcon: Image.asset('images/app_icon.png', width: 40.0, height: 40.0),
              children: <Widget>[Text('我是个比较正经的对话框内容...你可以随便把我替换成任何部件,只要你喜欢(*^▽^*)')],
            );
          }

         

      • 最后的效果:

      • 拓展
        AboutDialog会自带两个按钮 VIEW LICENSESCLOSEVIEW LICENSES会跳转一个 Flutter Licenses的网页,CLOSE会关闭,至于为什么是英文的,是因为我们没有设置语言的原因,这个涉及到多语言。 

 

三,Dialog 状态保持

  假如有个需求,需要在弹出的 Dialog显示当前被改变的值,然后通过按钮可以修改这个值 ,该如何实现。相信很多小伙伴都会这么认为,通过 setState来修改不就行了吗,没错,我一开始的确这么去实现的,我们先看下代码好了,增加一个 DialogState按钮,然后指向对应的点击事件。

  • 示例代码
    _showStateDialog() {
        showDialog(
            context: context,
            barrierDismissible: false,
            builder: (context) => SimpleDialog(
                  title: Text('我这边能实时修改状态值'),
                  contentPadding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
                  children: <Widget>[
                    Text('当前的值是: $_count', style: TextStyle(fontSize: 18.0)),
                    Padding(
                      padding: const EdgeInsets.symmetric(vertical: 12.0),
                      child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
                        RaisedButton(
                          onPressed: increase,
                          child: Text('点我自增'),
                        ),
                        RaisedButton(
                          onPressed: decrease,
                          child: Text('点我自减'),
                        ),
                        RaisedButton(
                          onPressed: () => Navigator.pop(context),
                          child: Text('点我关闭'),
                        )
                      ]),
                    )
                  ],
                ));
      }

     

  • 效果

  • 遇到问题
    怎么 Dialog的值不改变呢,明明界面上的已经修改了啊。所以说图样图森破咯,看下官方对 showDialog方法的解释吧
    /// This function takes a `builder` which typically builds a [Dialog] widget.
    /// Content below the dialog is dimmed with a [ModalBarrier]. The widget
    /// returned by the `builder` does not share a context with the location that
    /// `showDialog` is originally called from. Use a [StatefulBuilder] or a
    /// custom [StatefulWidget] if the dialog needs to update dynamically.
    糟糕透的翻译又来了:该方法通过 builder参数来传入一个 Dialog部件,dialog下的内容被一个「模态障碍」阻隔,builder的 context和调用 showDialog时候的 context不是共享的,如果需要动态修改 dialog的状态值,需要通过 StatefulBuilder或者自定义 dialog继承于 StatefulWidget来实现
  • 解决办法
    所以解决的方法很明确,对上面的代码进行修改,在外层嵌套一个 StatefulBuilder部件
     _showStateDialog() {
        showDialog(
            context: context,
            barrierDismissible: false,
            // 通过 StatefulBuilder 来保存 dialog 状态
            // builder 需要传入一个 BuildContext 和 StateSetter 类型参数
            // StateSetter 有一个 VoidCallback,修改状态的方法在这写
            builder: (context) => StatefulBuilder(
                builder: (context, dialogStateState) => SimpleDialog(
                      title: Text('我这边能实时修改状态值'),
                      contentPadding: const EdgeInsets.symmetric(horizontal: 12.0, vertical: 8.0),
                      children: <Widget>[
                        Text('当前的值是: $_count', style: TextStyle(fontSize: 18.0)),
                        Padding(
                          padding: const EdgeInsets.symmetric(vertical: 12.0),
                          child: Row(mainAxisAlignment: MainAxisAlignment.spaceAround, children: <Widget>[
                            RaisedButton(
                              // 通过 StatefulBuilder 的 StateSetter 来修改值
                              onPressed: () => dialogStateState(() => increase()),
                              child: Text('点我自增'),
                            ),
                            RaisedButton(
                              onPressed: () => dialogStateState(() => decrease()),
                              child: Text('点我自减'),
                            ),
                            RaisedButton(
                              onPressed: () => Navigator.pop(context),
                              child: Text('点我关闭'),
                            )
                          ]),
                        )
                      ],
                    )));
      }

     

  • 修改效果
      然后再运行下,可以看到 dialog和界面的值保持一致了

 


 

おすすめ

転載: www.cnblogs.com/lxlx1798/p/11371271.html