DartでのMVVMの書き方
公開日: 2024-05-06 15:24:03
今回はFlutterを使って書く際のDartでのMVVMのサンプルコードを作成したので、まとめていこうと思います。
ChatGPTを使っても結構修正箇所が出てしまっております。
基本的なフォルダ構成はこのようになっていて、libの中にはMVVMのフォルダとmain.dart (エントリーポイント)を配置する形になります。
lib
→model
→counter_model.dart
→view
→counter_view.dart
→viewmodel
→counter_view_model.dart
→main.dart
main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'view/counter_view.dart';
import 'viewmodel/counter_view_model.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider(
create: (_) => CounterViewModel(),
child: MaterialApp(
title: 'MVVM Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const CounterView(),
),
);
}
}
counter_model.dart
class CounterModel {
int count;
CounterModel(this.count);
}
counter_view_model.dart
import 'package:flutter/material.dart';
import '../model/counter_model.dart';
class CounterViewModel extends ChangeNotifier {
final CounterModel _counter = CounterModel(0);
int get count => _counter.count;
void increment() {
_counter.count++;
notifyListeners();
}
void decrement() {
_counter.count--;
notifyListeners();
}
}
counter_view.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import '../viewmodel/counter_view_model.dart';
class CounterView extends StatelessWidget {
// `super`パラメーターを使って、親クラスの`key`パラメーターを呼び出し
const CounterView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("MVVM Counter"), // アプリバーのタイトルを設定しています。
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// テキストウィジェットで固定のテキストを表示しています。
const Text('You have pushed the button this many times:'),
// Consumerウィジェットを使って`CounterViewModel`を取得し、カウンターの値を表示します。
Consumer<CounterViewModel>(
builder: (context, viewModel, child) {
return Text(
'${viewModel.count}', // カウンターの値をテキストで表示します。
style: Theme.of(context).textTheme.headlineMedium,
);
},
),
],
),
),
floatingActionButton: Column(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
FloatingActionButton(
// インクリメントボタンでカウンターの値を増やします。
onPressed: () => context.read<CounterViewModel>().increment(),
tooltip: 'Increment', // ボタンの説明テキスト
child: const Icon(Icons.add),
),
const SizedBox(height: 10), // ボタン間のスペース
FloatingActionButton(
// デクリメントボタンでカウンターの値を減らします。
onPressed: () => context.read<CounterViewModel>().decrement(),
tooltip: 'Decrement', // ボタンの説明テキスト
child: const Icon(Icons.remove),
),
],
),
);
}
}
実行結果

こちらのようなアップダウン機能をもったカウンターを作成しました。
Viewの書き方が、すごく特徴的なので、しっかり勉強していきます。