基本的に自分用のメモ書きです.
以下の記事がめちゃくちゃ参考になる.
特に以下のコマンドについてのページは覚えておきたい.
以下に実装例を示す.重要な箇所にはコメントを入れた.
dartclass ParentWidget extends StatefulWidget {
const ParentWidget({super.key});
@override
State<ParentWidget> createState() => _ParentWidgetState();
}
class _ParentWidgetState extends State<ParentWidget> {
// 親から子に渡される変数
int counterParent = 0;
final String buttonNameParent = 'Button Name';
// 親から子に渡される関数
void addCountParent() {
setState(() {
counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
// 子クラスの引数に渡す
body: ChildWidget(
counterChild: counterParent,
buttonNameChild: buttonNameParent,
addCountChild: addCountParent,
),
);
}
}
class ChildWidget extends StatefulWidget {
// 親クラスから受け取りたい変数をコンストラクタで受け取る
const ChildWidget({
Key? key,
required this.counterChild,
required this.buttonNameChild,
required this.addCountChild,
});
// 親クラスから受け取りたい変数宣言
final int counterChild;
final String buttonNameChild;
final Function addCountChild;
@override
State<ChildWidget> createState() => _ChildWidgetState();
}
class _ChildWidgetState extends State<ChildtWidget> {
@override
// widget.変数(関数) の形で使う
Widget build(BuildContext context) {
// 以下のreturn文をいい感じにしてください.
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Counter: ${widget.counterChild}',
style: TextStyle(fontSize: 24),
),
ElevatedButton(
onPressed: () => widget.addCountChild(),
child: Text(widget.buttonNameChild),
),
],
);
}
}
以下に実装例を示す.以下の実装では,スクロール限界までスクロールされたときに,メソッド(apiにGETリクエストを送信してリソースを取得)を呼び出して,リソースの追加を行っている.ほかにも無限スクロールを実現する方法はいろいろある.
dartclass _SampleWidgetState extends State<SampleWidget> {
List<Content> contents = [];
ScrollController _scrollController = ScrollController();
int currentPage = 1;
@override
void initState() {
super.initState();
// 最初のコンテンツ取得
_submission();
// 限界までスクロールされたかどうかの判定
_scrollController.addListener(() {
if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
_submissionMore();
}
});
}
@override
void dispose() {
_scrollController.dispose();
super.dispose();
}
void _submission() async {
final results = await getContents(1);
setState(() {
_currentPage = 1;
contents = results;
});
}
void _submissionMore() async {
// 限界までスクロールされた時の追加コンテンツ取得
final results = await getContents(currentPage + 1);
setState(() {
_currentPage++;
contents.addAll(results);
});
}
// ...
@override
Widget build(BuildContext context) {
// ...
ListView(
controller: _scrollController, // _scrollControllerを渡す
children: contents.map<ContentContainer>((value) {
return ContentContainer(value: value);
}).toList(),
),
// ...
}
}
// APIを呼び出して,コンテンツ取得
Future<List<Content>> getContents(int page) async {
// ...
final uri = Uri.https('example.com', '/api/v1', {
'offset': page.toString(),
});
// ...
return contents;
}
Listをmap関数でListViewのchildrenに,List型をmap関数で渡すことがある(以下みたいに).
dartList<Item> listItem = [];
ListView(
children: listItem.map<Item>((value) {
return MyWidget(item: value);
}).toList(),
)
ここで,各子WidgetであるMyWidgetに対してlistItemのindexを渡したいときがあったりする(ランキングで順位を表示させたいときとか).
この時は,以下のようにasMap関数を使うとよい.
dartList<Item> listItem = [];
ListView(
children: listItem.asMap().entries.map<Item>((entry) {
return MyWidget(item: entry.value, index: entry.key);
}).toList(),
)
以下のように,toLocalメソッドを使うと,ローカルタイムゾーンにできる.ただし注意点として,エミュレーターでは,UTCタイムゾーンが使われていたりする(何かしらの方法で設定変更できる?).
dartDateTime.now().toLocal()
WebView埋め込み型を実現したければ,以下のように実装するだけでよい(ドキュメント通りに実装するとよい).
dartcontroller = WebViewController()
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setBackgroundColor(const Color(0x00000000))
..setNavigationDelegate(
NavigationDelegate(
onProgress: (int progress) {
// Update loading bar.
},
onPageStarted: (String url) {},
onPageFinished: (String url) {},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
if (request.url.startsWith('https://www.youtube.com/')) {
return NavigationDecision.prevent;
}
return NavigationDecision.navigate;
},
),
)
..loadRequest(Uri.parse('https://flutter.dev')
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Flutter Simple Example')),
body: WebViewWidget(controller: controller),
);
}
↑のWebView埋め込み型のところに書いてあるコードは使えないので注意(たぶん古い?).