본문 바로가기
프로그래밍/Flutter & Dart

Flutter로 ToDo앱 만들기 (feat. GitHub)

by 어느덧중반 2020. 5. 22.
반응형

ToDo 앱에서는 클라우드 DB를 활용하는 앱이다.

할일 추가하기, 할일 완료하기, 할일 삭제하기, 할일 추가/완료/삭제시 클라우드DB인 Firestore에서 데이터 관리

 

Step1. git repository 만들고 연결

Step2. ToDo앱 기본버전 작성


Step1. git repository 만들고 연결

- flutter app 생성 > 프로젝트 열기 > VCS > Import into Version Control > Create Git Repository

- flutter_todo_app 선택

- Git init > Yes 클릭 > (다음캡쳐본 보면 알겠지만) 모든 파일들이 빨간 표시로 보임

- flutter_todo_app 우클릭 > Git > Add (Git에 내 프로젝트들 Add 시키자)

- VCS > Import into Version Control > Share Project on GitHub (GitHub에 공유)
  ✏️캡쳐본은 파일들 빨간색인데 원래는 Add후에 초록색으로 변경될것임)

- Repository name 설정 후 Share 클릭

- GitHub에서 new repository 확인 가능


Step2. ToDo앱 기본버전 작성

1. 기본코드 준비

2. 변수 준비

3. 전체 UI 작성

4. ToDo list UI 작성

5. 전체 UI와 ToDo list 결합

6. 기능 작성

7. 기능과 UI 연결

 

1. 기본코드 준비

- ToDo class 만들기(할일, 현재상태)

- ToDoPage Stateful Widget

import 'package:flutter/material.dart';

class ToDo {
  bool isDone = false; // 현재 진행여부
  String title; // 할일

  ToDo(this.title);
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ToDo App',
      theme: ThemeData(
        primarySwatch: Colors.green,
      ),
      home: ToDoListPage(),
    );
  }
}

class ToDoListPage extends StatefulWidget {
  @override
  _ToDoListPageState createState() => _ToDoListPageState();
}

class _ToDoListPageState extends State<ToDoListPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('남은 할 일'),
      ),
      body: Container(),
    );
  }
}

 

2. 변수 준비

이제 할 일 목록을 저장할 변수와 입력받은 할 일 문자열을 조작하는 컨트롤러가 필요 (TextEditingController)

class _ToDoListPageState extends State<ToDoListPage> {
  // 할일 저장할 리스트
  final _items = <ToDo>[];
  // 할일 문자열 다룰 컨트롤러
  var _todoController = TextEditingController();

  @override
  void dispose() {
    _todoController.dispose(); // 컨트롤러는 종료시 반드시 해제해줘야 함
    super.dispose();
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
      ...
  }

 

3. 전체 UI 작성

- 할일 입력받는 TextField, 추가버튼, 할일목록 리스트 코드 작성

- ListView는 Column의 children으로 포함될 때 반드시 Expanded로 감싸야 화면에 표시된다.

Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('남은 할 일'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Column(
          children: <Widget>[
            Row(
              children: <Widget>[
                Expanded(
                  child: TextField(
                    
                  ),
                ),
                RaisedButton(
                  onPressed: () {

                  },
                  color: Colors.green,
                  child: Text('추가하기', style: TextStyle(color: Colors.white),),
                )
              ],
            ),
            Expanded(
              child: ListView(
                children: <Widget>[],
              ),
            )
          ],
        ),
      ),
    );
  }

4. 할 일 목록 UI 작성

- 할일을 작성하고 추가하게 되면 ListTile로 만들고 ListView에 추가시켜주는 원리 (만드는 부분 별도 메소드로 작성)

- 할일을 작성하고 추가버튼 클릭시 ToDo 객체를 받아서 처리 후 위젯 리턴

  Widget _buildItemWidget(ToDo todo) {
    return ListTile(
      onTap: () { // 클릭하면 완료/취소 등의 작업을 할 예정

      },
      trailing: IconButton(
        icon: Icon(Icons.delete),
        onPressed: () {
          
        },
      ),
      title: Text(
        todo.title,
        style: todo.isDone? // 할일 완료 여부로 스타일 변경
          TextStyle(
            decoration: TextDecoration.lineThrough, // 취소선
            fontStyle: FontStyle.italic, // 이탤릭체
          ) : null, // 할일 중이면 아무 작업 안함
      ),
    );
  }

 

5. 전체 UI와 할 일 목록 결합

- build() 메소드에서 전체UI에서 표시할 할일 목록을 추가하자

- _items 리스트의 항목을 map()함수를 통해 todo 인수로 받고 _buildItemWidget() 메소드 반환. 그 후 toList()를 통해 리스트로..

            Expanded(
              child: ListView(
                children: _items.map((todo) => _buildItemWidget(todo)).toList(),
              ),
            )

 

6. 기능 작성 : _ToDoListPageState 내에 메소드 만들기

- 할일 추가

- 할일 삭제

- 할일 완료/미완료

  // 할 일 추가 메소드
  void _addTodo(Todo todo) {
    setState(() {
      _items.add(todo);
      _todoController.text = ''; // 할일을 리스트에 추가하며 할일 입력 필드 비우기
    });
  }

  // 할 일 삭제 메소드
  void _deleteTodo(Todo todo) {
    setState(() {
      _items.remove(todo);
    });
  }

  // 할 일 완료/미완료 메소드
  void _toggleTodo(Todo todo) {
    setState(() {
      todo.isDone = !todo.isDone;
    });
  }

 

7. 기능과 UI 연결

- build() 메소드 내 추가버튼을 누르면 _addTodo()가 실행되도록 설정

                Expanded(
                  child: TextField(
                    controller: _todoController, // 입력한 TextField 컨트롤러로 조작
                  ),
                ),
                RaisedButton(
                  onPressed: () => _addTodo(Todo(_todoController.text)),
                  color: Colors.green,
                  child: Text('추가하기', style: TextStyle(color: Colors.white),),
                )

- 할일 목록에서 ListTile을 클릭했을 때 완료/미완료 동작하도록 설정

    return ListTile(
      onTap: () => _toggleTodo(todo), // 완료/미완료 상태변경
      trailing: IconButton(
        icon: Icon(Icons.delete),
        onPressed: () => _deleteTodo(todo), // 할일 삭제하기
      ),
      title: Text(
        todo.title,
        style: todo.isDone? // 할일 완료 여부로 스타일 변경
          TextStyle(
            decoration: TextDecoration.lineThrough, // 취소선
            fontStyle: FontStyle.italic, // 이탤릭체
          ) : null, // 할일 중이면 아무 작업 안함
      ),
    );

할일 추가하기
할일 완료/미완료하기, 할일 삭제하기

 

반응형

댓글