Dart 関数

関数の基本形

1
2
3
戻り値の型 function_name (引数の型 引数名) {
return 戻り値;
}

名前付きパラメータ

  • {} で引数を囲むと、呼び出す際に名前の指定が必要に
  • {} で引数を囲むと、任意の引数になる
  • 必須にしたければ @required アノテーションをつける
  • 引数の一部だけに使う場合は、末尾にもってくる
1
2
3
4
5
6
7
8
# 定義
void example({bool bold, bool hidden}) {....};

# 呼び出し
example(bold: true, hidden: false);

# 引数を必須にする
void example({@required bool bold, bool hidden}) {....};

オプショナルパラメータ

  • [] で引数を囲むと、任意の引数になる
  • 引数の一部だけに使う場合は、末尾にもってくる
1
2
3
4
5
# 定義
String say(String from, [String msg]) {...};

# 呼び出し
say('Bob');

デフォルト値

  • 名前付きパラメータ、オプショナルパラメータ ともにデフォルト値を設定可能
1
String say({String from = 'Bob'}, [String msg = 'hello']) {...};

匿名関数

1
2
3
(引数の型 引数名) {
return 戻り値;
}
1
2
3
4
var hello = (name) {
return 'Hello, ${name}';
}
print(hello('foo'));

Flutter Multi-child layout Widgets

公式ドキュメント - Multi-child layout widgets
https://flutter.dev/docs/development/ui/widgets/layout#Multi-child%20layout%20widgets

  • レイアウトするウィジェット
  • childrenプロパティを持つウィジェットで使える
Widget 説明
Column 縦方向にウィジェットを並べる
Row 横方向にウィジェットを並べる
Stack ウィジェットを重ねる
Positioned Stackウィジェットの子要素の位置を指定
Expanded Row, Columnウィジェットを余白一杯まで広げる
Flexible 親ウィジェットのサイズ変更に合わせて自サイズも変化する
Wrap childrenで指定したウィジェットの合計サイズが端末より大きくなった場合に折り返す
Table スクロールしない表を作る
IndexedStack 複数のウィジェットを切り替えられる

Flutter Single-child layout Widgets

公式ドキュメント - Single-child layout widgets
https://flutter.dev/docs/development/ui/widgets/layout#Single-child%20layout%20widgets

  • レイアウトするウィジェット
  • childプロパティを持つウィジェットで使える
Widget 説明
Container 他のウィジェットの入れ物となる
BoxDecoration ボックスをカスタマイズ
SizedBox 指定したサイズの箱を作れる
Align childに指定したウィジェットの配置を指定できる
Center childに指定したウィジェットの配置を指定できる
FractionallySizedBox 子のサイズを画面幅・高さの割合で指定できる
Padding childに指定したウィジェットと親ウィジェットとの距離を指定できる
EdgeInsets 箱の上下左右のオフセット値を指定できる
ConstrainedBox childに指定したウィジェットに制約を追加できる
BoxConstraints 箱に制約を付けられる
FittedBox 親ウィジェットのサイズにどのように収めるかをBoxFit列挙型で指定できる
AspectRatio ウィジェットのアスペクト比を一定に保つ
LimitedBox ListViewのように子にサイズを与えない場合、このウィジェットでラップしてサイズを与えて表示させる
Spacer スペースを取れる
LayoutBuilder 画面表示前にウィジェットのサイズを知り、子ウィジェットのレイアウトを決めたい場合に利用する

Dart言語 演算子

条件式

  • conditionがtrueならexpr1を計算して返す、そうでなければ、expr2を計算して返す
1
condition ? expr1 : expr2
  • expr1が非nullの時はその値を返す、そうでなければ、expr2を計算して返す
1
expr1 ?? expr2

Conditional member access operator「?.」

https://dart.dev/guides/language/language-tour#overridable-operators

  • オブジェクト(レシーバー)がnullの場合にメソッドを呼ぶとエラーになるので、エラーにせずに戻り値としてnullを返す事が出来る演算子
1
2
String target = null;
var length = target?.trim()?.toLowerCase()?.length ?? 0; // 結果は「0」

カスケード記法 「..」

https://dart.dev/guides/language/language-tour#cascade-notation-

  • レシーバーのオブジェクトを返す演算子
  • 一時変数を作成する手間が省け、簡潔な記述が出来る
1
2
3
4
5
6
7
8
final addresBook = (AddressBookBuilder()
...name = '山田'
...email = 'test@example.com'
...phone = (PhoneNumberBuilder()
...number = '999-9999-9999'
...label = 'home')
.build())
.build();

Spreads記法 「…」「…?」

https://dart.dev/guides/language/language-tour#spread-operator

  • リストの全ての要素を別のリストに挿入できる演算子
1
2
3
var list = [1, 2, 3];
var list2 = [0, ...list];
assert(list2.length == 4);
  • nullの可能性がある場合は「…?」を使う
1
2
3
var list;
var list2 = [0, ...?list];
assert(list2.length == 1);
  • 利用例
1
2
3
4
5
6
7
8
9
10
11
12
Widget build(BuildContext context) {
return CupertionPageScaffold(
child: Column(
children: [
buildHeader(),
...buildContents(),
...buildContents2(),
buildFooter(),
],
),
);
}

Collection if

  • リストに作成時に値を含めるかどうかの条件分岐を記述できる
1
2
3
4
5
6
var nav = [
'Home',
'Furniture',
'Plants',
if (promoActive) 'Outlet'
];
  • 利用例
1
2
3
4
5
6
7
8
9
10
11
12
Widget build(BuildContext context) {
return CupertionPageScaffold(
child: Column(
children: [
buildHeader(),
...buildContents(),
if (wantContents2) ...buildContents2(),
buildFooter(),
],
),
);
}

Collection for

  • リスト作成時に、別のリストを操作しながらリストに追加する処理を記述できる
1
2
3
4
5
6
7
var listOfInts = [1, 2, 3];
var listOfStrings = [
'#0'
for (var i in listOfStrings) '#$i'
];
assert(listOfStrings[1] == '#1');
assert(listOfStrings.length == 4);

Dart Futureクラス

Future

  • 非同期処理を簡潔に扱うための仕組み
  • 他の言語では、プロミス と呼ばれる
1
2
3
4
5
6
7
8
9
repository.fetchUser(100).then((User user) {
return repository.fetchCompany(user.companyId);
}).then((Company company) {
// 成功時の処理
}).catchError(error) {
// エラー時の処理
}).whenComplete() {
// どちらかが終わったら呼ばれる
});

async/await

  • Futureクラスの記述の可読性をあげるシンタックスシュガー
  • 戻り値は、Future型でないと利用できないので注意
  • 上のコードを以下のように書く事が出来る
1
2
3
4
5
6
7
8
9
10
11
Future<String> findCompanyName(int userId) async {
try {
var user = await repository.fetchuser(userId);
var company = await repository.fetchCompany(user.companyId);
return company.name;
} catch(error) {
// エラー時の処理
} finally {
// 終了時の処理
}
}

FlutterでLinter設定

Linterとは、ソースコードを解析して、エラー、バグ、スタイルエラー、疑わしい記述を知らせてくれるツール

プロジェクトのルートに「analysis_options.yaml」ファイルを設置して、ルールを記述すれば利用可能

Flutterリポジトリにある analysis_options.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# Specify analysis options.
#
# Until there are meta linter rules, each desired lint must be explicitly enabled.
# See: https://github.com/dart-lang/linter/issues/288
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
# See the configuration guide for more
# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
#
# There are other similar analysis options files in the flutter repos,
# which should be kept in sync with this file:
#
# - analysis_options.yaml (this file)
# - packages/flutter/lib/analysis_options_user.yaml
# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
#
# This file contains the analysis options used by Flutter tools, such as IntelliJ,
# Android Studio, and the `flutter analyze` command.

analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
# treat missing returns as a warning (not a hint)
missing_return: warning
# allow having TODOs in the code
todo: ignore
# Ignore analyzer hints for updating pubspecs when using Future or
# Stream and not importing dart:async
# Please see https://github.com/flutter/flutter/pull/24528 for details.
sdk_version_async_exported_from_core: ignore
exclude:
- "bin/cache/**"
# the following two are relative to the stocks example and the flutter package respectively
# see https://github.com/dart-lang/sdk/issues/28463
- "lib/i18n/messages_*.dart"
- "lib/src/http/**"

linter:
rules:
# these rules are documented on and in the same order as
# the Dart Lint rules page to make maintenance easier
# https://github.com/dart-lang/linter/blob/master/example/all.yaml
- always_declare_return_types
- always_put_control_body_on_new_line
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
- always_require_non_null_named_parameters
- always_specify_types
- annotate_overrides
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
# - avoid_as # required for implicit-casts: true
- avoid_bool_literals_in_conditional_expressions
# - avoid_catches_without_on_clauses # we do this commonly
# - avoid_catching_errors # we do this commonly
- avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime
- avoid_empty_else
# - avoid_equals_and_hash_code_on_mutable_classes # not yet tested
- avoid_field_initializers_in_const_classes
- avoid_function_literals_in_foreach_calls
# - avoid_implementing_value_types # not yet tested
- avoid_init_to_null
# - avoid_js_rounded_ints # only useful when targeting JS runtime
- avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested
# - avoid_print # not yet tested
# - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
# - avoid_returning_null # there are plenty of valid reasons to return null
# - avoid_returning_null_for_future # not yet tested
- avoid_returning_null_for_void
# - avoid_returning_this # there are plenty of valid reasons to return this
# - avoid_setters_without_getters # not yet tested
# - avoid_shadowing_type_parameters # not yet tested
# - avoid_single_cascade_in_expression_statements # not yet tested
- avoid_slow_async_io
- avoid_types_as_parameter_names
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
# - avoid_unnecessary_containers # not yet tested
- avoid_unused_constructor_parameters
- avoid_void_async
# - avoid_web_libraries_in_flutter # not yet tested
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
# - cascade_invocations # not yet tested
# - close_sinks # not reliable enough
# - comment_references # blocked on https://github.com/flutter/flutter/issues/20765
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
- control_flow_in_finally
# - curly_braces_in_flow_control_structures # not yet tested
# - diagnostic_describe_all_properties # not yet tested
- directives_ordering
- empty_catches
- empty_constructor_bodies
- empty_statements
# - file_names # not yet tested
- flutter_style_todos
- hash_and_equals
- implementation_imports
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
- iterable_contains_unrelated_type
# - join_return_with_assignment # not yet tested
- library_names
- library_prefixes
# - lines_longer_than_80_chars # not yet tested
- list_remove_unrelated_type
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
- no_adjacent_strings_in_list
- no_duplicate_case_values
# - no_logic_in_create_state # not yet tested
- non_constant_identifier_names
# - null_closures # not yet tested
# - omit_local_variable_types # opposite of always_specify_types
# - one_member_abstracts # too many false positives
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
- overridden_fields
- package_api_docs
- package_names
- package_prefixed_library_names
# - parameter_assignments # we do this commonly
- prefer_adjacent_string_concatenation
- prefer_asserts_in_initializer_lists
# - prefer_asserts_with_message # not yet tested
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
# - prefer_constructors_over_static_methods # not yet tested
- prefer_contains
# - prefer_double_quotes # opposite of prefer_single_quotes
- prefer_equal_for_default_values
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
- prefer_final_fields
# - prefer_final_in_for_each # not yet tested
- prefer_final_locals
# - prefer_for_elements_to_map_fromIterable # not yet tested
- prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
# - prefer_int_literals # not yet tested
# - prefer_interpolation_to_compose_strings # not yet tested
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
# - prefer_mixin # https://github.com/dart-lang/language/issues/32
# - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932
# - prefer_relative_imports # not yet tested
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
# - provide_deprecation_message # not yet tested
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
- recursive_getters
- slash_for_doc_comments
# - sort_child_properties_last # not yet tested
- sort_constructors_first
- sort_pub_dependencies
- sort_unnamed_constructors_first
- test_types_in_equals
- throw_in_finally
# - type_annotate_public_apis # subset of always_specify_types
- type_init_formals
# - unawaited_futures # too many false positives
# - unnecessary_await_in_return # not yet tested
- unnecessary_brace_in_string_interps
- unnecessary_const
# - unnecessary_final # conflicts with prefer_final_locals
- unnecessary_getters_setters
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
- unnecessary_new
- unnecessary_null_aware_assignments
- unnecessary_null_in_if_null_operators
- unnecessary_overrides
- unnecessary_parenthesis
- unnecessary_statements
- unnecessary_this
- unrelated_type_equality_checks
# - unsafe_html # not yet tested
- use_full_hex_values_for_flutter_colors
# - use_function_type_syntax_for_parameters # not yet tested
- use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
# - void_checks # not yet tested
© 2020 GitHub, Inc.

implicit-casts: false

型推論で暗黙的キャストをしないように

implicit-dynamic: false

型推論で型を決定できない場合に「dynamic」型にしないように

include: package:pedantic/analysis_options.yaml

includeで読み込んでいる場合は「pubspec.yaml」に記述する

1
2
dev_dependencies:
pedantic: any

厳し目のルールでいくなら「pedantic_mono」パッケージがオススメ

Dart/Flutter の静的解析強化のススメ

以下が導入手順

1.
pedantic_monoパッケージをインストール

1
2
dev_dependencies:
pedantic_mono: any

1.
analysis_options.yamlを配置
https://github.com/mono0926/pedantic_mono/blob/master/example/analysis_options.yaml

AndroidStudioでFlutterコードフォーマット設定

Android Studioで、Flutterのコードフォーマット設定をする。

次の2箇所にチェックを入れればOK

- Format code on save
- Oragnize imports on save 

Flutterバージョン

Flutterのバージョン一覧

1
flutter version

プロジェクトのFlutterバージョンを確認

1
flutter --version

プロジェクトのFlutterバージョンを指定バージョンに変更

1
flutter version v1.9.1+hotfix.3

チャンネル別の最新バージョンを調べるなら、公式サイトを参照

公式 Flutter SDK releases

Dart言語 コンストラクタ

クラスと同じ名前の関数がコンストラクタ

生成的コンストラクタ(一般的なコンストラクタ)

1
2
3
4
5
6
7
8
9
class Color {
int red;
int green;
int blue;
Color({int red, int green, int blue}) {
this.red = red;
this.green = green;
this.blue = blue;
}

自動フィールド初期化

  • Dartで使われる一般的な書き方
  • 上のコードと同じ意味
1
2
3
4
5
6
7
class Color {
int red;
int green;
int blue;
// 同名のフィールドに自動代入する
Color(this.red, this.green, this.blue);
}

名前付きコンストラクタ

  • クラスに複数のコンストラクタを実装できる
  • それぞれのコンストラクタの意味を明確に出来る
1
2
3
4
5
6
7
8
9
10
11
12
class Color {
int red;
int blue;
int green;

// 別の引数を受け取るコンストラクタを作成
Color.fromString(String colorText) {
this.red = int.parse(colorText.substring(0, 2), radix: 16);
this.blue = int.parse(colorText.substring(2, 4), radix: 16);
this.green = int.parse(colorText.substring(4, 6), radix: 16);
}
}

コンストラクタのリダイレクト

1
2
3
4
5
6
7
8
9
10
11
12
class Child extends Base {
// 親クラスの「名前付きコンストラクタ」を呼び出す
Child(String value): super.fromString(value);

// 親クラスの「通常のコンストラクタ」を呼び出す
Child.ex(): super('test') {
//...
};

// 自クラスの別の「名前付きコンストラクタ」を呼び出す
Child.delegate(): this.fromString('');
}

初期化リスト

  • コンストラクタ本体を実行する前に、インスタンス変数を初期化できる
1
2
3
4
5
6
7
8
class Line {
final int length;
final Color color;

// 何か処理を実行してからフィールドに代入する
Line({@required this.length, @required String colorText}):
this.color = Color.fromString(colorText);
}

初期化される処理の順序

  1. 初期化リスト (initializer list)
  2. スーパークラスのコンストラクタ
  3. 子クラスのコンストラクタ

初期化リスト + assert機能

1
2
3
4
5
6
7
8
9
class Article {
final String title;
final String body;

// 引数の条件確認を行う
Article({@required this.title, @required this.body}):
assert(title != null),
assert(body != null);
}
1
2
3
4
5
6
7
class Item extends Base {
final String name;

Item({@required this.name}):
asesrt(name != null),
supser(); // 親クラスのコンストラクタを呼び出す場合は最後に書く
}

ファクトリコンストラクタ

  • ファクトリコンストラクタはインスタンスが作成されない
  • シングルトンのデザインパターンで利用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
clas GlobalContext() {
static GlobalContext _instance;

// 「_」から始まるのでprivateなコンストラクタ
GlobalContext._() {
//...
}

// ファクトリコンストラクタで「生成的コンストラクタ」を使う
factory GlobalContext() {
if (_instance == null) {
_instance = GlobalContext._();
}
return _instance;
}

// ファクトリコンストラクタで「名前付きコンストラクタ」を使う
factory GlobalContext.getWithRefresh() {
_instance = null;
return GlobalContext();
}
}

定数コンストラクタ

  • コンパイル時に定数オブジェクトをインスタンス化したい場合に利用
  • コンストラクタには「const」キーワードを付け、「const」キーワードでインスタンスを生成
1
2
3
4
5
6
7
8
9
10
11
12
class Pet{
final name;
const Pet(this.name);
}

final dog = const Pet('Pochi');

void main(){
final Pet cat = new Pet('Mike');
print(dog.name); // => Pochi
print(cat.name); // => Mike
}
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×