๋ฐ์ํ
๐ฉTodoList App ๋ง๋ค๊ธฐ ๋ชฉํ
1. ํด๋ ๊ตฌ์กฐ ์ก๊ธฐ
2. main ํ์ผ ๋ง๋ค์ด ๋ณด๊ธฐ
3. Model ํด๋์ค ์์ฑํด๋ณด๊ธฐ
4. View ๋ง๋ค์ด ๋ณด๊ธฐ
5. ViewModel ๋ง๋ค์ด ๋ณด๊ธฐ
6. view(todo_list_view.dart) ์ ๋ฐ์ดํฐ ๋ถ๋ฆฌ ํ๊ธฐ
1. ํ๋ก์ ํธ ๊ตฌ์กฐ ๊ตฌ์ฑํ๊ธฐ
2. main.dart ์ฝ๋ ์์ฑํ๊ธฐ
import 'package:flutter/material.dart';
void main() {
runApp(const TodoApp());
}
class TodoApp extends StatelessWidget {
const TodoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
appBar: AppBar(title: const Text("TodoList"),),
body: Center(
child: Text("My Todo"),
),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:my_todo_mvvm/views/todo_list_view.dart';
void main() {
runApp(const TodoApp());
}
class TodoApp extends StatelessWidget {
const TodoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
appBar: AppBar(title: const Text("TodoList"),),
body: TodoListView(),
),
),
);
}
}
3. Model ํด๋์ค ์์ฑํด๋ณด๊ธฐ
/models/todo_item.dart ํ์ผ ์์ฑํ๊ธฐ
// Model
class TodoItem {
String title;
bool isDone;
TodoItem({required this.title, this.isDone = false});
}
4. view ๋ง๋ค์ด ๋ณด๊ธฐ
/views/todo_list_view.dart ํ์ผ ์์ฑํ๊ธฐ (1๋จ๊ณ)
import 'package:flutter/material.dart';
// View ํด๋์ค
class TodoListView extends StatefulWidget {
const TodoListView({super.key});
@override
State<TodoListView> createState() => _TodoListViewState();
} // end of TodoListView class
class _TodoListViewState extends State<TodoListView> {
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: 'Enter todo item...',
suffix: IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
// build() ๋ฉ์๋ ์ฌ ํธ์ถ
_controller.clear();
});
},
)
),
),
],
),
);
}
} // end of _TodoListViewState
TextEditingController๋ TextField ์์ ฏ์์ ์ฌ์ฉ์ ์ ๋ ฅ์ ๊ด๋ฆฌํ๋๋ฐ ์ฌ์ฉ๋๋ ํด๋์ค์ ๋๋ค. ์ด๋ฅผ ํตํด TextField์์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅํ ๊ฐ์ ์ ๊ทผํ๊ฑฐ๋, TextField์ ๊ฐ์ ๋ณ๊ฒฝํ๊ฑฐ๋, TextField๋ฅผ ์ด๊ธฐํํ๋ ๋ฑ ๋ค์ํ ์์ ์ ์ํํ ์ ์์ต๋๋ค.
- ์
๋ ฅ๊ฐ ์ ๊ทผ:
- *TextEditingController*๋ _controller.text ํ๋กํผํฐ๋ฅผ ํตํด ํ์ฌ **TextField*์ ์ ๋ ฅ๋ ๊ฐ์ ๊ฐ์ ธ์ฌ ์ ์์ต๋๋ค. ์ฌ์ฉ์๊ฐ **TextField*์ ์ ๋ ฅํ ๋ด์ฉ์ ๊ฐ์ ธ์์ ๋ก์ง์ ํ์ฉํ๊ฑฐ๋ ๋ค๋ฅธ ๊ณณ์ ํ์ํ ์ ์์ต๋๋ค.
- ์
๋ ฅ๊ฐ ๋ณ๊ฒฝ:
- *_controller.text = 'newValue'*์ ๊ฐ์ด **TextEditingController*์ text ํ๋กํผํฐ๋ฅผ ํตํด **TextField*์ ๊ฐ์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
- ์
๋ ฅ๊ฐ ์ด๊ธฐํ:
- *TextEditingController*์ clear ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ **TextField*์ ๋ด์ฉ์ ์ฝ๊ฒ ์ง์ธ ์ ์์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉ์๊ฐ ์ ๋ ฅ์ ์๋ฃํ ํ ์ ๋ ฅ ํ๋๋ฅผ ์ด๊ธฐํํ ๋ ์ ์ฉํฉ๋๋ค.
- ์
๋ ฅ ๋ณ๊ฒฝ ๊ฐ์ง:
- *TextEditingController*์ ๋ฆฌ์ค๋๋ฅผ ์ถ๊ฐํ์ฌ **TextField*์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋ฆผ์ ๋ฐ์ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ ๋ ฅ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋ ํน์ ๋์์ ์ํํ๋๋ก ์ค์ ํ ์ ์์ต๋๋ค.
ํ๋ฉด ๋ง๋ค๊ธฐ 2๋จ๊ณ
import 'package:flutter/material.dart';
import 'package:my_todo_mvvm/models/todo_item.dart';
// View ํด๋์ค
class TodoListView extends StatefulWidget {
const TodoListView({super.key});
@override
State<TodoListView> createState() => _TodoListViewState();
} // end of TodoListView class
class _TodoListViewState extends State<TodoListView> {
final TextEditingController _controller = TextEditingController();
// ์ํ ๋ฐ์ดํฐ ๋ง๋ค์ด ๋ณด๊ธฐ
List<TodoItem> _todoItems = [
TodoItem(title: 'ํ๋ฌํฐ ๊ณต๋ถํ๊ธฐ', isDone: false),
TodoItem(title: '๋ฎ์ ์๊ธฐ', isDone: true),
];
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: 'Enter todo item...',
suffix: IconButton(
icon: Icon(Icons.add),
onPressed: () {
setState(() {
// build() ๋ฉ์๋ ์ฌ ํธ์ถ
_controller.clear();
});
},
),
),
),
//
Expanded(
child: ListView.builder(
itemCount: _todoItems.length,
itemBuilder: (context, index) {
var item = _todoItems[index];
// ๋๊ฐ์ ์ธ์ ๊ฐ์ ๋ฐ์์ ์์ ฏ์ ๋ฆฌํด ์ํค๋ฉด ๋๋ค.
return ListTile(
title: Text(item.title),
trailing: Checkbox(
value: item.isDone,
onChanged: (value) {
print("value : ${value}");
setState(() {
_todoItems[index].isDone = value ?? false;
});
},
),
);
},
),
),
],
),
);
}
} // end of _TodoListViewState
ViewModel ๋ง๋ค๊ธฐ
// ViewModel
import 'package:my_todo_mvvm/models/todo_item.dart';
class TodoListViewModel {
// ํ๋ฉด ์ฌ์ฉ๋ ๋ฐ์ดํฐ
List<TodoItem> _items = []; // private
// get ๋ฉ์๋ ๋ง๋ค์ด ์ฃผ๊ธฐ
List<TodoItem> get items => _items;
// ๋ฆฌ์คํธ์ TodoItem ๊ฐ์ฒด๋ฅผ ์ถ๊ฐํ๋ ๋ฉ์๋ ๋ง๋ค๊ธฐ
void addItem(String title) {
_items.add(TodoItem(title: title, isDone: false));
}
void toggleItem(TodoItem todo) {
todo.isDone = !todo.isDone;
}
}
todo_list_view.dart ์์
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:my_todo_mvvm/models/todo_item.dart';
import 'package:my_todo_mvvm/view_models/todo_list_view_model.dart';
// View ํด๋์ค
class TodoListView extends StatefulWidget {
const TodoListView({super.key});
@override
State<TodoListView> createState() => _TodoListViewState();
} // end of class
class _TodoListViewState extends State<TodoListView> {
final TextEditingController _controller = TextEditingController();
final TodoListViewModel listViewModel = TodoListViewModel();
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
children: [
TextField(
controller: _controller,
decoration: InputDecoration(
hintText: 'Enter Todo Item',
suffix: IconButton(
icon: Icon(Icons.add),
onPressed: (){
setState(() {
listViewModel.addItem(_controller.text);
_controller.clear();
});
},
)
),
),
//
Expanded(
child: ListView.builder(
itemCount: listViewModel.items.length,
itemBuilder: (context, index){
var item = listViewModel.items[index];
// ๋๊ฐ ์ธ์๊ฐ์ ๋ฐ์์ ์์ ฏ์ ๋ฆฌํด
return ListTile(
title: Text(item.title),
trailing: Checkbox(
value: item.isDone,
onChanged: (value) {
print('value : ${value}');
setState(() {
listViewModel.toggleItem(item);
});
},
),
);
},),
)
],
),
);
}
} // end of _TodoListViewState
๋ฐ์ํ
'Flutter' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
typedef์ ํจ์ (0) | 2024.03.30 |
---|---|
dart ์ด๋ก (0) | 2024.03.30 |
Flutter MVVM ํจํด - 1 (0) | 2024.03.19 |
dart ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ - 3 (0) | 2024.03.15 |
dart ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ - 2 (0) | 2024.03.15 |