「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>Flutter]]
--[[Flutterのファースト・ステップ]]
--[[Flutterのセカンド・ステップ]]
--[[Flutterのサード・ステップ]]
--Flutterの4thステップ
--[[Flutterの5thステップ]]

*目次 [#q3193e80]
#contents

*概要 [#d0e5c30b]
[[Flutter]] の step by step(其の四)。

*手順1:業務ぃーな、CRUDを実装してみる。 [#d0496641]

**入力フォームの作成 [#kafe8fef]
-公式のサンプルに問題があるらしい。
-取り敢えず、基本のTextFormFieldを使ってみる。

***前編 [#dc5979d3]
-ファースト・ステップ~
以下のような感じ。
 // main.dart
 Form(
   child: Column(
     children: [
       TextFormField(
         decoration: InputDecoration(labelText: 'id'),
       ),
       TextFormField(
         decoration: InputDecoration(labelText: 'password'),
         obscureText: true, // 追加
       ),
     ],
   ),
 )

-セカンド・ステップ~
以降、[[技術は熱いうちに打て>#o3109b1b]]が参考になる。

--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属性。

***後編 [#a826eb3e]
-サード・ステップ

--現状値の保存に対して、現状値の設定は?~
FormFieldStateにGlobalKey<FormFieldState>張って、~
GlobalKey<FormFieldState>.currentState?.didChange(this._XXXX)。

--ドロップダウンリスト~
[[DropdownButton>Flutterのファースト・ステップ#mbd05014]]を使用する。

--バリデーション処理が長い。
---implements Validatableで部品化が可能。
---[[カスタム・コントロール>#gd4970e7]]的なコトも可能。

**一覧表示の作成 [#j6f8b2ea]

***[[WebAPIでデータを取得する。>Flutterのファースト・ステップ#k0b7d0c5]] [#sb8e48be]

***JSONをdecodeする。 [#le6af3e5]
decodeするdart:convertライブラリのサンプルが複数ある。

-JSON.decodeは古いライブラリ。

-今は、jsonDecodeのライブラリを使用する。

-以下の何れかの方に変換される模様。
--Map<String, dynamic>
--List<dynamic>

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

***DataTableを使用した一覧 [#vc52168b]
-業務系では、DataTableのWidgetが使えそう。

-Bindingは、DataTableの、
--columns: で、列定義を行い、
--rows: で、DataRow / DataCellのlistを返す。

***ListViewを使用した一覧 [#m8020487]
-ListView.builderのitemBuilderでcardデザインを返す。
-cardデザインは[[プッシュ通知>Flutterのサード・ステップ#p7b4ca10]]のサンプル中に含まれる。

***, etc. [#oc5559f6]

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

-[Flutter]入力フォームのインラインバリデーションを実装する | DevelopersIO~
https://dev.classmethod.jp/articles/flutter-inline-validation/

-dart - How to add dynamically items to the table in flutter? - Stack Overflow~
https://stackoverflow.com/questions/53997496/how-to-add-dynamically-items-to-the-table-in-flutter

***Qiita [#t26ef242]
-Flutter Form系Widgetの使い方 〜 すべてのWidgetを学習~
https://qiita.com/kurun_pan/items/3378875ff034614f381a

-お前らのFormのサンプルコードはすべて間違っている~
https://qiita.com/hummer/items/8f1ba5ae09d31f42a465

-【初心者】Flutter:APIでデータ取得して、一覧表示させるサンプルアプリ~
https://qiita.com/yasutaka_ono/items/6d2a0d3b0856598f9788

*手順2:気になっている所を修正する。 [#q42ac453]

**画面遷移処理 [#m3ff833d]
-画面内の遷移と[[Drawerの遷移>Flutterのファースト・ステップ#a39c49ff]]がゴッチャになる。

-調べていくと、最初に表示された画面は、~
ルートなので、ソレ以上、POPできないらしい。

-以下の修正を加えると、ソレっぽくなる。

***画面内の遷移は、[[スタックにプッシュする。>Flutterのファースト・ステップ#ve163562]] [#c2806f2e]
故に、戻る処理は、
-基本的に、戻るボタンで前画面に戻る。
-処理次第でpopを明示的に実装する。

***[[Drawerの遷移>Flutterのファースト・ステップ#a39c49ff]]は、一度スタックを空にする。 [#je4c8223]
以下のように実装する。

-ルートへの遷移~
ルートまで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の部品化 [#p264249e]
-[[全体構成の見直し>Flutterのサード・ステップ#dd29a972]] の [[common>Flutterのサード・ステップ#u6459cfd]]に入れる。

-StatelessWidgetでラップする方法と、~
Widgetをextendsする方法がある模様。
--前者は、簡単な特化型のカスタマイズ
--後者は、高難易度の汎化型のカスタマイズ

-C#的に言うと、
--StatelessWidgetでラップする方法~
ユーザ・コントロール的にラップするか?
--Widgetをextendsする方法~
[[カスタム・コントロール>https://techinfoofmicrosofttech.osscons.jp/index.php?.NET%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%AB%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E6%96%B9%E6%B3%95]]化するか?

>みたいな。

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

***Drawer [#b5f0071c]
-StatelessWidgetでラップする方法
--定義して
 import 'package:flutter/material.dart';
 
 class MyDrawer extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return Drawer(

--使用する。
 return Scaffold(
   ...,
   drawer: MyDrawer(),
 );

***Button [#ee2d48f4]
-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 [#gd4970e7]
-対象の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. [#v5e6a9fc]

**その他の共通化 [#r91b2e7d]
[[全体構成の見直し>Flutterのサード・ステップ#dd29a972]] の 各フォルダに入れる。


***変数/定数クラス [#haae6266]
→ [[configs>Flutterのサード・ステップ#vc2278c4]]

***関数クラス [#e46b7b58]
→ [[helpers>Flutterのサード・ステップ#u4ee8972]]

***サービス・クラス [#wd1132bc]
→ [[services>Flutterのサード・ステップ#o8aca8f8]]

**参考 [#xea15178]
-dart - Persisting AppBar Drawer across all Pages Flutter~
https://stackoverflow.com/questions/51659805/persisting-appbar-drawer-across-all-pages-flutter

-ボタンを「コンポーネント化」しよう|Flutter ボタン自作入門~
https://zenn.dev/heavenosk/books/flutter-button-diy/viewer/extracting_button

-Creating Custom Form Fields in Flutter~
by AbdulRahman AlHamali | SAUGO 360 | Medium~
https://medium.com/saugo360/creating-custom-form-fields-in-flutter-85a8f46c2f41

*[[参考>Flutter#a9ed99c8]] [#b96b3900]

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS