Flutter
Dart
Flutter
- Flutter documentation | Flutter
- Cookbook | Flutter
- pub.dev
- Flutterの効率良い学び方
- Flutter実践入門
- /Solido/awesome-flutter
- flutterawesome.com
- Tips
- Roadmap
example 集
- flutter.github.io/samples
- gallery.flutter.dev
- flutter/gallery
- flutter/samples
- itsallwidgets.com
- nisrulz/flutter-examples
オープンソースのアプリケーション
- https://github.com/TheAlphamerc/flutter_twitter_clone
- https://github.com/burhanrashid52/WhatTodo
- https://github.com/GeekyAnts/flutter-login-home-animation
- https://github.com/yumemi-inc/flutter-training-template
レイアウト
ナビゲーション
i18n
状態管理
Inside Flutter
- Inside Flutter | Flutter
- Flutter の Widget ツリーの裏側で起こっていること
- Stateful Widget のパフォーマンスを考慮した正しい扱い方
- 【Flutter】Navigator.of(context) から理解する 3つのツリー
stateful widget
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Text('$_counter'),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
),
);
}
}
InheritedWidget
ChangeNotifier
class Counter {
int value = 0;
}
class CounterNotifier extends ChangeNotifier {
Counter counter = Counter();
void increment() {
counter.value++;
notifyListeners();
}
}
class MyHomePage extends StatelessWidget {
MyHomePage({super.key});
final counterNotifier = CounterNotifier();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: AnimatedBuilder(
animation: counterNotifier,
builder: (BuildContext context, Widget? child) {
return Text('${counterNotifier.counter.value}');
},
),
floatingActionButton: FloatingActionButton(
onPressed: counterNotifier.increment,
),
);
}
}
ValueNotifier
class MyHomePage extends StatelessWidget {
MyHomePage({super.key});
final counterNotifier = ValueNotifier(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: AnimatedBuilder(
animation: counterNotifier,
builder: (BuildContext context, Widget? child) {
return Text('${counterNotifier.value}');
},
),
floatingActionButton: FloatingActionButton(
onPressed: () => counterNotifier.value++,
child: const Icon(Icons.add),
),
);
}
}
Provider
StateNotifier
provider
+ flutter_state_notifier
:
import 'package:provider/provider.dart';
import 'package:state_notifier/state_notifier.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';
void main() {
runApp(StateNotifierProvider<CounterNotifier, Counter>(
create: (_) => CounterNotifier(),
child: const MyApp(),
));
}
@immutable
class Counter {
final int value;
const Counter({this.value = 0});
}
class CounterNotifier extends StateNotifier<Counter> {
CounterNotifier() : super(const Counter());
void increment() {
state = Counter(value: state.value + 1);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
final counterNotifier = Provider.of<CounterNotifier>(context);
return Scaffold(
appBar: AppBar(),
body: Text("${counter.value}"),
floatingActionButton: FloatingActionButton(
onPressed: counterNotifier.increment,
),
);
}
}
Riverpod
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(const ProviderScope(child: MyApp()));
}
@immutable
class Counter {
final int value;
const Counter({this.value = 0});
}
class CounterNotifier extends StateNotifier<Counter> {
CounterNotifier() : super(const Counter());
void increment() {
state = Counter(value: state.value + 1);
}
}
final counterProvider =
StateNotifierProvider<CounterNotifier, Counter>((ref) => CounterNotifier());
class MyHomePage extends ConsumerWidget {
const MyHomePage({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final counter = ref.watch(counterProvider);
final counterNotifier = ref.watch(counterProvider.notifier);
return Scaffold(
appBar: AppBar(),
body: Text("${counter.value}"),
floatingActionButton: FloatingActionButton(
onPressed: counterNotifier.increment,
),
);
}
}