코딩(개발)/Flutter

todolist(firebase) step2

플랜데버 2021. 3. 12. 17:59

*pubspec.yaml

dependencies:
  flutter:
    sdk: flutter
  cloud_firestore: ^0.14.4
  firebase_core: ^0.5.3

 

 

* model\todo.dart

class Todo {
  String uid;
  String subject;
  String memo;
  bool isComplet;
  String date;

  Todo({this.uid, this.subject, this.memo, this.isComplet, this.date});
}

 

* services\database_services.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:sql_example/todofirebase/model/todo.dart';

class DatabaseService {
  CollectionReference todosCollection =
      FirebaseFirestore.instance.collection("todo");

  Future createNewTodo(String subject, String memo) async {
    return await todosCollection.add({
      "subject": subject,
      "memo": memo,
      "isComplet": false,
    });
  }

  Future completTask(uid) async {
    await todosCollection.doc(uid).update({"isComplet": true});
  }

  Future removeTodo(uid) async {
    await todosCollection.doc(uid).delete();
  }

  List<Todo> todoFromFirestore(QuerySnapshot snapshot) {
    if (snapshot != null) {
      return snapshot.docs.map((e) {
        return Todo(
          isComplet: e.data()["isComplet"],
          subject: e.data()["subject"],
          memo: e.data()["memo"],
          uid: e.id,
        );
      }).toList();
    } else {
      return null;
    }
  }

  Stream<List<Todo>> listTodos() {
    return todosCollection.snapshots().map(todoFromFirestore);
  }
}

 

*todolist.dart

import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
import 'package:sql_example/todofirebase/loding.dart';
import 'package:sql_example/todofirebase/services/database_services.dart';
import 'package:sql_example/todofirebase/model/todo.dart';

class TodoList extends StatefulWidget {
  @override
  _TodoListState createState() => _TodoListState();
}

class _TodoListState extends State<TodoList> {
  TextEditingController _subject = TextEditingController();
  TextEditingController _memo = TextEditingController();

  bool isComplet = false;
  @override
  Widget build(BuildContext context) {
    return FutureBuilder<Object>(
        future: Firebase.initializeApp(),
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Scaffold(
              body: Center(child: Text(snapshot.error.toString())),
            );
          }
          if (snapshot.connectionState == ConnectionState.waiting) {
            return Loading();
          }
          return Scaffold(
            appBar: AppBar(
              title: Text('todolist firebase'),
            ),
            body: StreamBuilder<Object>(
                stream: DatabaseService().listTodos(),
                builder: (context, snapshot) {
                  if (!snapshot.hasData) {
                    return Loading();
                  }
                  List<Todo> todos = snapshot.data;

                  return SafeArea(
                    child: Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: SingleChildScrollView(
                        child: Column(
                          children: [
                            Text("all todos"),
                            Divider(),
                            SizedBox(height: 20),
                            ListView.separated(
                              separatorBuilder: (context, index) => Divider(
                                color: Colors.grey[800],
                              ),
                              shrinkWrap: true,
                              itemCount: todos.length,
                              itemBuilder: (context, index) {
                                return Dismissible(
                                  key: Key(todos[index].subject),
                                  background: Container(
                                    decoration: BoxDecoration(
                                        color: Colors.grey,
                                        borderRadius: BorderRadius.all(
                                            Radius.circular(5))),
                                    padding: EdgeInsets.only(right: 10),
                                    alignment: Alignment.centerRight,
                                    child: Icon(
                                      Icons.delete,
                                      color: Colors.white,
                                      size: 30,
                                    ),
                                  ),
                                  onDismissed: (direction) async {
                                    //print("remove");
                                    await DatabaseService()
                                        .removeTodo(todos[index].uid);
                                  },
                                  child: ListTile(
                                    onTap: () {
                                      DatabaseService()
                                          .completTask(todos[index].uid);
                                      print('check' + todos[index].uid);
                                    },
                                    title: Text(
                                      todos[index].subject,
                                      style: TextStyle(
                                          fontSize: 20,
                                          fontWeight: FontWeight.w600),
                                    ),
                                    subtitle: Text(
                                      todos[index].memo,
                                      style: TextStyle(fontSize: 16),
                                    ),
                                    trailing: Container(
                                      padding: EdgeInsets.all(2),
                                      height: 30,
                                      width: 30,
                                      decoration: BoxDecoration(
                                        color: Theme.of(context).primaryColor,
                                        shape: BoxShape.circle,
                                      ),
                                      child: todos[index].isComplet
                                          ? Icon(
                                              Icons.check,
                                              color: Colors.white,
                                            )
                                          : Container(),
                                    ),
                                  ),
                                );
                              },
                            )
                          ],
                        ),
                      ),
                    ),
                  );
                }),
            floatingActionButtonLocation:
                FloatingActionButtonLocation.centerFloat,
            floatingActionButton: FloatingActionButton(
              child: Icon(Icons.add),
              onPressed: () {
                showDialog(
                  context: context,
                  child: SimpleDialog(
                    contentPadding:
                        EdgeInsets.symmetric(horizontal: 25, vertical: 20),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(20)),
                    title: Row(
                      children: [
                        Text(
                          "Add Todo",
                          style: TextStyle(fontSize: 20),
                        ),
                        Spacer(),
                        IconButton(
                          icon: Icon(
                            Icons.cancel,
                            color: Colors.grey,
                            size: 30,
                          ),
                          onPressed: () {
                            Navigator.pop(
                                context); //실행할 내용이 한 줄일때는  onPressed: () =>  Navigator.pop(context); 이렇게 써도 된다.
                          },
                        )
                      ],
                    ),
                    children: [
                      Divider(),
                      TextFormField(
                        controller: _subject,
                        autofocus: true,
                        style: TextStyle(height: 1.5, fontSize: 18),
                        decoration: InputDecoration(
                            hintText: "과목을 입력하세요",
                            hintStyle: TextStyle(color: Colors.black38)),
                      ),
                      TextFormField(
                        controller: _memo,
                        autofocus: true,
                        style: TextStyle(height: 1.5, fontSize: 18),
                        decoration: InputDecoration(
                            hintText: "내용을 입력하세요",
                            hintStyle: TextStyle(color: Colors.black38)),
                      ),
                      // Container( //dialog 크키 하드하게 정해줄때 사용
                      //   height: 500,
                      //   width: MediaQuery.of(context).size.width,
                      // )
                      SizedBox(height: 20),
                      SizedBox(
                        //  width: MediaQuery.of(context).size.width,
                        height: 50,
                        child: FlatButton(
                          shape: RoundedRectangleBorder(
                              borderRadius: BorderRadius.circular(5)),
                          child: Text("Add"),
                          color: Theme.of(context).primaryColor,
                          textColor: Colors.white,
                          onPressed: () {
                            if (_subject.text.isNotEmpty) {
                              Logger().d(_subject.text);
                              if (_subject.text.isNotEmpty) {
                                DatabaseService().createNewTodo(
                                  _subject.text.trim(),
                                  _memo.text.trim(),
                                );
                                _memo.clear();
                                _subject.clear();
                              }

                              //Navigator.pop(context); //창닫히게
                            }
                          },
                        ),
                      )
                    ],
                  ),
                );
              },
            ),
          );
        });
  }
}

 

 

 

영상참조

https://www.youtube.com/watch?v=yx8p_0xJzf0