はじめに
Udemyで習った内容の備忘録のためのものです.
到達目的
- 例外や失敗時のための処理の仕方
- 使用した関数の理解
内容
下記が理解したいコードです,郵便番号のAPIの実装のためのコードです.
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController controller = TextEditingController();
List<String> items = [];
String errorMessage = '';
Future<void> loadZipCode(String zipCode) async {
setState(() {
errorMessage = 'APIレスポンス待ち';
});
final response = await http.get(
Uri.parse('https://zipcloud.ibsnet.co.jp/api/search?zipcode=$zipCode'));
if (response.statusCode != 200) {
// 失敗
return;
}
//成功
final body = json.decode(response.body) as Map<String, dynamic>;
final results = (body['results'] ?? []) as List<dynamic>;
if (results.isEmpty) {
setState(() {
errorMessage = 'そのような郵便番号の住所はありません';
});
} else {
setState(() {
errorMessage = '';
items = results
.map((result) =>
"${result['address1']}${result['address2']}${result['address3']}")
.toList(growable: false);
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
controller: controller,
keyboardType: TextInputType.number,
onChanged: (value) {
if (value.isNotEmpty) {
loadZipCode(value);
}
},
),
),
body: ListView.builder(
itemBuilder: (context, index) {
if (errorMessage.isNotEmpty) {
return ListTile(title: Text(errorMessage));
} else {
return ListTile(title: Text(items[index]));
}
},
itemCount: items.length,
),
);
}
}
1.MyAppWidget
MyApp
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
main
関数に呼び出されるルートWidgetで,このWidgetで宣言されたものから実行されていく.最初に渡す引数やUI構築のための変数などもここで宣言される
解釈
アプリケーションを構築するための最初のWidgetで初期設定などここで設定する.
2. MyhomePageウィジェット
MyhomePage
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController controller = TextEditingController();
List<String> items = [];
String errorMessage = '';
....
}
上記のコードについて, MyApp
で呼び出されるなウィジェット.ここで変化する対象である変数やウィジェットを宣言する.
3. loadZipCode関数
loadZipCode
Future<void> loadZipCode(String zipCode) async {
setState(() {
errorMessage = 'APIレスポンス待ち';
});
final response = await http.get(
Uri.parse('https://zipcloud.ibsnet.co.jp/api/search?zipcode=$zipCode'));
if (response.statusCode != 200) {
// 失敗
return;
}
//成功
final body = json.decode(response.body) as Map<String, dynamic>;
final results = (body['results'] ?? []) as List<dynamic>;
if (results.isEmpty) {
setState(() {
errorMessage = 'そのような郵便番号の住所はありません';
});
} else {
setState(() {
errorMessage = '';
items = results
.map((result) =>
"${result['address1']}${result['address2']}${result['address3']}")
.toList(growable: false);
});
}
上記の内容についてわからない単語がちょくちょく出てきたので,下記にまとめました.
項目 | 内容 | 解釈 |
---|---|---|
Future | 非同期プログラミング.操作が完了した場合のみ通知し,値は返さない関数 | 成功したら通知のみしてくれるvoid関数 |
async & await | 非同期プログラミングのための処理.特定タスクの完了を待たずに実行させることを目的としている. | asyncは非同期関数であることの宣言.awaitはどの処理を待つかを宣言するためのもの |
dynamic | any型 | どんな変数でも行ける.しかし,どんな値をコンパイラ時点で扱うのかはわからない |
5. Buildメソッド
loadZipCode
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: TextField(
controller: controller,
keyboardType: TextInputType.number,
onChanged: (value) {
if (value.isNotEmpty) {
loadZipCode(value);
}
},
),
),
body: ListView.builder(
itemBuilder: (context, index) {
if (errorMessage.isNotEmpty) {
return ListTile(title: Text(errorMessage));
} else {
return ListTile(title: Text(items[index]));
}
},
itemCount: items.length,
),
);
}
上記のコードが基本的なUIについての内容です.TextFiled
がテキストを読み込むためのUIで,ListViewがAPI通信で得た内容の表示のためのコードです.
itemCount: items.length,
はListViewのための引数です.ListViewのアイテム表示をいくつするかを表したものです.