.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。

目次

概要

Flutter の step by step(其の四)。

手順1:業務ぃーな、CRUDを実装してみる。

入力フォームの作成

  • 公式のサンプルに問題があるらしい。
  • 取り敢えず、基本のTextFormField?を使ってみる。

前編

  • ファースト・ステップ
    以下のような感じ。
    // main.dart
    Form(
      child: Column(
        children: [
          TextFormField(
            decoration: InputDecoration(labelText: 'id'),
          ),
          TextFormField(
            decoration: InputDecoration(labelText: 'password'),
            obscureText: true, // 追加
          ),
        ],
      ),
    )
  • doneボタンが押された時の処理を記述
  • doneからnextに変更しフォーカス移動
  • 初期値設定と現状値の保存
  • インライン・バリデーション処理の実装
  • ポイント
  • その1: 意味もなくsave()するな。
    単に、子要素のonSave()を呼ぶ処理なので。
  • その2: 意味もなくステートを持つな。
    FormにGlobalKey?<FormState?>張って、
    GlobalKey?<FormState?>.currentState?.save()で上記のonSave()が動作。
  • その3: やたらめったらFormを書き換えるな。
    要するに、setStateを書かなくてもイイというコトらしい。
  • その4: 初期値を入れるのにTextEditingController?を使うな。
    TextFormField?.initialValueを使用する。
  • その5: AutofillHints?ちゃんと書こう。
    HTML.Inputタグで言うところのautocomplete属性。

後編

  • サード・ステップ
  • 現状値の保存に対して、現状値の設定は?
    FormFieldState?GlobalKey?<FormFieldState?>張って、
    GlobalKey?<FormFieldState?>.currentState?.didChange(this._XXXX)。

一覧表示の作成

WebAPIでデータを取得する。

JSONをdecodeする。

decodeするdart:convertライブラリのサンプルが複数ある。

  • JSON.decodeは古いライブラリ。
  • 今は、jsonDecodeのライブラリを使用する。
  • 以下の何れかの方に変換される模様。
    • Map<String, dynamic>
    • List<dynamic>

DBの一覧ならList<dynamic>になる。

DataTable?を使用した一覧

  • 業務系では、DataTable?のWidgetが使えそう。
  • Bindingは、DataTable?の、
    • columns: で、列定義を行い、
    • rows: で、DataRow? / DataCell?のlistを返す。

ListView?を使用した一覧

  • ListView?.builderのitemBuilderでcardデザインを返す。
  • cardデザインはプッシュ通知のサンプル中に含まれる。

, etc.

参考

  • 【誰でも分かる!】FlutterのFormを一から
    作りながら解説してみたよ | 技術は熱いうちに打て!
    https://blog.dalt.me/2036

Qiita

手順2:気になっている所を修正する。

画面遷移処理

  • 調べていくと、最初に表示された画面は、
    ルートなので、ソレ以上、POPできないらしい。
  • 以下の修正を加えると、ソレっぽくなる。

画面内の遷移は、スタックにプッシュする。

故に、戻る処理は、

  • 基本的に、戻るボタンで前画面に戻る。
  • 処理次第でpopを明示的に実装する。

Drawerの遷移は、一度スタックを空にする。

以下のように実装する。

  • ルートへの遷移
    ルートまでpopする。
    onTap: () {
      while(Navigator.of(context).canPop()){
        Navigator.of(context).pop();
      }
    },
  • ルート以外への遷移
    ルートまでpopした後、1つダケpushする。
    onTap: () {
      while(Navigator.of(context).canPop()){
        Navigator.of(context).pop();
      }
      Navigator.of(context).pushNamed("/appauth");
    },

Widgetの部品化

  • StatelessWidget?でラップする方法と、
    Widgetをextendsする方法がある模様。
    • 前者は、簡単な特化型のカスタマイズ
    • 後者は、高難易度の汎化型のカスタマイズ
  • C#的に言うと、
    • StatelessWidget?でラップする方法
      ユーザ・コントロール的にラップするか?
    • Widgetをextendsする方法
      カスタム・コントロール化するか?

みたいな。

  • Windows Formsのようなオナー・ドローは不要。
    WPFのように子要素で実装可能(Widget buildメソッドで返す)。

Drawer

  • StatelessWidget?でラップする方法
    • 定義して
      import 'package:flutter/material.dart';
      
      class MyDrawer extends StatelessWidget {
        @override
        Widget build(BuildContext context) {
          return Drawer(
  • 使用する。
    return Scaffold(
      ...,
      drawer: MyDrawer(),
    );

Button

  • StatelessWidget?でラップする方法
    • 定義して
      import 'package:flutter/material.dart';
      
      class MyElevatedButton extends StatelessWidget {
      
        final String _caption;
        final VoidCallback _onPressed;
      
        const MyElevatedButton(
            this._caption, this._onPressed,
            {Key? key}) : super(key: key);
      
        @override
        Widget build(BuildContext context) {
          return ElevatedButton(
            child: Text(this._caption),
            ...,
            ),
            onPressed: this._onPressed,
          );
        }
      }
  • 使用する。
    MyElevatedButton('EnglishWords Button', this._englishWords),

FormField?

  • 対象のWidgetをextends する方法
  • 定義して
    class CounterFormField extends FormField<int> {
    
      CounterFormField({
        FormFieldSetter<int> onSaved,
        FormFieldValidator<int> validator,
        int initialValue = 0,
        bool autovalidate = false
      }) : super(
        onSaved: onSaved,
        validator: validator,
        initialValue: initialValue,
        autovalidate: autovalidate,
        builder: (FormFieldState<int> state) {
          return Row(
           この中で、state.valueとかstate.didChangeが使える。
          );
        }
      );
    }
  • 使用する。
    CounterFormField(
      autovalidate: false,
      validator: (value) {
        ...
      },
      onSaved: (value) => this._value = value,
    )

, etc.

その他の共通化

全体構成の見直し の 各フォルダに入れる。

変数/定数クラス

configs

関数クラス

helpers

サービス・クラス

services

参考

参考


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2021-07-02 (金) 09:36:03 (23d)