플러터(Flutter)로 Todo app 만들기
Flutter를 사용하여 할 일 앱을 만들려면 Flutter 프레임워크와 Dart 프로그래밍 언어에 대한 기본 지식이 필요합니다. 할 일 앱을 만드는 일반적인 단계는 다음과 같습니다.
- 선호하는 개발 환경에서 새 Flutter 프로젝트를 설정합니다.
- 할 일 목록에 대한 새 파일을 만들고 할 일 항목에 대한 클래스를 정의합니다. 이 클래스에는 작업 이름, 설명 및 작업 완료 여부에 대한 부울에 대한 속성이 있어야 합니다.
- 위젯을 사용 ListView하여 스크롤 가능한 목록에 할 일 항목을 표시합니다.
- 새 할 일 항목을 추가하기 위한 양식을 만듭니다. 여기에는 TextField작업 이름 및 설명에 대한 위젯과 새 항목을 목록에 추가하는 버튼이 포함될 수 있습니다.
- 기존 할 일 항목을 업데이트하고 삭제하는 기능을 추가합니다.
- 사용자가 작업을 완료로 표시할 수 있도록 체크박스 또는 토글 버튼을 추가합니다.
- 완료 여부에 따라 할 일 항목의 스타일을 다르게 지정하려면 조건부 서식을 사용하세요.
- 앱을 테스트하고 필요한 조정을 합니다.
이것은 매우 높은 수준의 개요이며 상태, 유효성 검사, 사용자 인터페이스 등을 처리하는 데 필요한 더 많은 세부 정보가 있음을 유의하십시오.
간단 버전
import 'package:flutter/material.dart';
class Todo {
String task;
String description;
bool isCompleted;
Todo({this.task, this.description, this.isCompleted = false});
}
class TodoList extends StatefulWidget {
@override
_TodoListState createState() => _TodoListState();
}
class _TodoListState extends State<TodoList> {
List<Todo> _todos = [];
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo App'),
),
body: ListView.builder(
itemCount: _todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_todos[index].task),
subtitle: Text(_todos[index].description),
trailing: Checkbox(
value: _todos[index].isCompleted,
onChanged: (bool value) {
setState(() {
_todos[index].isCompleted = value;
});
},
),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
// Show form to add new todo
},
child: Icon(Icons.add),
),
);
}
}
이것은 Todo 앱의 시작점으로 사용할 수 있는 것의 단순화된 버전입니다. 이것은 완전한 작동 응용 프로그램이 아니라는 점에 유의하십시오. 데이터 저장 및 로드, 사용자 입력 처리 및 유효성 검사, 작업 삭제 및 업데이트 처리 등과 같은 몇 가지 중요한 기능이 누락되어 있습니다. 또한 상태 관리, 라우팅을 처리하지 않습니다. 및 Flutter 애플리케이션의 다른 중요한 측면. Flutter에 대해 자세히 알아보고 완전한 애플리케이션을 구축하는 방법을 배우려면 몇 가지 자습서 또는 온라인 과정을 따르시기 바랍니다.
고도화된 버전
다음은 새 할 일 항목 추가, 기존 항목 편집 및 삭제, 저장소에 데이터 유지와 같은 더 많은 기능을 포함하는 더 자세한 Todo 앱 버전입니다.
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Todo {
String task;
String description;
bool isCompleted;
Todo({this.task, this.description, this.isCompleted = false});
Map<String, dynamic> toJson() => {
'task': task,
'description': description,
'isCompleted': isCompleted,
};
}
class TodoList extends StatefulWidget {
@override
_TodoListState createState() => _TodoListState();
}
class _TodoListState extends State<TodoList> {
List<Todo> _todos = [];
final _formKey = GlobalKey<FormState>();
final _taskController = TextEditingController();
final _descriptionController = TextEditingController();
@override
void initState() {
super.initState();
_loadTodos();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Todo App'),
),
body: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: _todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_todos[index].task),
subtitle: Text(_todos[index].description),
trailing: Checkbox(
value: _todos[index].isCompleted,
onChanged: (bool value) {
setState(() {
_todos[index].isCompleted = value;
_saveTodos();
});
},
),
onLongPress: () {
_showTodoBottomSheet(index);
},
);
},
),
),
],
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_showAddTodoBottomSheet();
},
child: Icon(Icons.add),
),
);
}
void _showAddTodoBottomSheet() {
_taskController.clear();
_descriptionController.clear();
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
controller: _taskController,
decoration: InputDecoration(labelText: 'Task'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter a task';
}
return
return null;
},
),
TextFormField(
controller: _descriptionController,
decoration: InputDecoration(labelText: 'Description'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter a description';
}
return null;
},
),
SizedBox(height: 20.0),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
setState(() {
_todos.add(Todo(
task: _taskController.text,
description: _descriptionController.text));
_saveTodos();
Navigator.pop(context);
});
}
},
child: Text('Save'),
),
],
),
),
);
});
}
void _showTodoBottomSheet(int index) {
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(_todos[index].task),
Text(_todos[index].description),
SizedBox(height: 20.0),
RaisedButton(
onPressed: () {
setState(() {
_todos.removeAt(index);
_saveTodos();
Navigator.pop(context);
});
},
child: Text('Delete'),
),
SizedBox(height: 20.0),
RaisedButton(
onPressed: () {
Navigator.pop(context);
_showEditTodoBottomSheet(index);
},
child: Text('Edit'),
),
],
),
);
});
}
void _showEditTodoBottomSheet(int index) {
_taskController.text = _todos[index].task;
_descriptionController.text = _todos[index].description;
showModalBottomSheet(
context: context,
builder: (context) {
return Container(
padding: EdgeInsets.all(20.0),
child: Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextFormField(
controller: _taskController,
decoration: InputDecoration(labelText: 'Task'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter a task';
}
return null;
},
),
TextFormField(
controller: _descriptionController,
decoration: InputDecoration(labelText: 'Description'),
validator: (value) {
if (value.isEmpty) {
return 'Please enter a description';
}
return null;
},
),
SizedBox(height: 20.0),
RaisedButton(
onPressed: () {
if (_formKey.currentState.validate()) {
setState(() {
_todos[index].task = _taskController.text;
_todos[index].description = _descriptionController.text;
_saveTodos();
Navigator.pop(context);
});
}
},
child: Text('Save'),
),
],
),
),
);
});
}
void _saveTodos() {
List<String> todos = [];
for (Todo todo in _todos) {
todos.add(todo.toString());
}
_prefs.setStringList('todos', todos);
}
}
이 코드는 작업을 추가, 편집 및 삭제할 수 있는 Todo 앱을 생성합니다. TextFormField 를 사용하여 사용자 입력을 수락하고 데이터를 List
이것은 기본 예제이며 더 많은 기능을 추가할 수 있으며 로컬 컴퓨터에서 테스트하고 오류가 있는지 확인하고 디버그하는 것이 좋습니다.
'expert' 카테고리의 다른 글
플러터로 Hello World 앱 만들기 (0) | 2023.01.28 |
---|---|
Flutter/React-Native/Android-Native 앱용 SHA-1 생성 (0) | 2023.01.28 |
Cloud Firestore를 업데이트한 후: '[]' 연산자가 '객체' 유형에 대해 정의되지 않았습니다. 연산자 '[]'를 정의해 보세요. (0) | 2023.01.28 |
오류: iOS에서 flutter를 실행할 때 'Flutter/Flutter.h' 파일을 찾을 수 없습니다. (0) | 2023.01.28 |
POST 요청을 수행하는 동안 Flutter CERTIFICATE_VERIFY_FAILED 오류를 해결하는 방법은 무엇입니까? (0) | 2023.01.28 |
댓글