welcome to my blog

[Flutter] ToDo List 정리 본문

Flutter

[Flutter] ToDo List 정리

_annie_ 2021. 10. 27. 20:10
728x90

일정관리 어플을 만들어보면서 헷갈렸던 부분이나 까먹을것 같은 내용 정리

전체 코드는 하단참고

 

완성 화면

 

만들 기능 : 

1. 텍스트박스에 글씨를 적고 Add버튼을 누르면 하단에 내용이 추가된다.

2. 휴지통 모양의 버튼을 누르면 해당 항목이 삭제된다.

3. 체크박스를 클릭하면 완료되었다는 의미로 취소선을 표시한다.

 

사용라이브러리 : GetX

//version
get 4.3.8

//command
flutter pub add get

//pubspec.yaml
dependencies:
  get: ^4.3.8

 

 

1. UI 구성

필요한 위젯 :

스케쥴 입력 부분 : Textfield(입력) / TextButton(추가) / Divider(없어도됨)

등록된 스케쥴 표시 부분 : ListView(목록표시) / ListTile(ListView의 항목) / Checkbox(체크) / Text(스케쥴표시) / Icon(휴지통) / GestureDetector(Icon 제스처감지)

ListView의 하위 위젯으로 ListTile을 추가하고,

ListTile의 하위 위젯으로 checkbox, text, icon를 추가한다.

 

2. controller 등록

  1.  lib 디렉토리 하위에 controller 디렉토리 생성
  2.  GetxController를 상속받는 class 생성
  3. 변수 및 메서드 작성
  4. 메서드동작 시 변수를 변경하고 싶다면 마지막에 update(); 작성해줄 것
import 'package:get/get.dart';
import 'package:todo/view/todo_list_tile.dart';

class TodoController extends GetxController {
  List<TodoListTile> todoArray = <TodoListTile>[].obs;

  //item 등록
  void addItem(String item) {
    	todoArray.add(TodoListTile(itemText: item));
    	update();
  	}
  }

 

controller사용

만약 추후 Get으로 라우터기능을 사용할 것이라면 상위 위젯을 MaterialApp  대신 GetMaterialApp로 사용

(아니면 기존 MaterialApp사용해도 상관없음)

GetBuilder로 컨트롤러에 접근

GetMaterialApp(
      home: GetBuilder<TodoController>(
          init: TodoController(),
          builder: (controller) {
            return Scaffold(
              appBar: AppBar(
                title: Text('To do'),
              ),
          }
      )
  )

작성한 컨트롤러(TodoController)를 init에 생성시켜주고

controller에 접근해서 사용

 

부모위젯에서 등록한 컨트롤러를 자식 위젯에서는 어떻게 쓰지! -> Widget build 부분에서 Get.find 사용하여 controller에 접근

final TodoController controller = Get.find();

 

 

 

사용 컨트롤 관련 정리: 

 

  • Textfield

Textfield의 값(value)을 읽어오는 방법 :

TextField에 TextEditingController 생성 및 연결하고 controller.text 로 접근가능

//TextEditingController 선언
TextEditingController todoTextEditingController = TextEditingController();


//위젯과 연결
TextField(
    controller: widget.todoTextEditingController,
    maxLines: 1,
)

//사용
widget.todoTextEditingController.text

 

  • ButtonStyle
ButtonStyle(
	backgroundColor:
		MaterialStateProperty.resolveWith((states) {
		if (states.contains(MaterialState.pressed)) {
			return Colors.orange;
		} else {
			return Colors.yellow;
		}
	}),
	overlayColor: MaterialStateProperty.resolveWith(
	(states) => Colors.redAccent),
)

버튼 style 속성에 적용

기본상태일때 색상 : yellow

버튼을 꾹 누를때 (혹은 클릭할때) : 배경색상 orange

버튼 클릭한곳 색상 : redAccent

 

  • Divider

가로선을 긋고 싶을 때 사용

const Divider(
	thickness: 1,
	color: Colors.grey,
),

 

  • Checkbox
Checkbox(
        checkColor: Colors.yellow,
        fillColor: MaterialStateProperty.resolveWith((states) => Colors.deepPurple),
        value: widget.isChecked,
        onChanged: (bool? value) {
          setState(() {
            widget.isChecked = value!;
          });
        },
      )

checkColor : 체크박스의 박스내부 체크아이콘의 색상

fillColor: 체크박스가 체크되었을 때 배경색상설정

value : 현재 상태 (체크/미체크)

onChanged: 체크박스를 선택했을 때 상태변경된경우

 

  • ListView

itemBuilder에 표현해 줄 위젯작성

itemCount에 표현할 위젯의 개수 작성

ListView.builder(
	itemBuilder: (context, index) {
		return _.todoArray[index];
	},
	itemCount: _.todoArray.length,
),

현재 코드에서는 todoArray라는 위젯 리스트를 넣어주었다.

 

//main.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:todo/controller/todo_controller.dart';

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

class ToDoApp extends StatefulWidget {
  ToDoApp({Key? key}) : super(key: key);
  // TodoController todoController = Get.put(TodoController());
  TextEditingController todoTextEditingController = TextEditingController();

  @override
  _ToDoAppState createState() => _ToDoAppState();
}

class _ToDoAppState extends State<ToDoApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: GetBuilder<TodoController>(
          init: TodoController(),
          builder: (_) {
            return Scaffold(
              appBar: AppBar(
                title: Text('To do'),
              ),
              body: Column(
                children: [
                  Flexible(
                    flex: 1,
                    child: Padding(
                      padding: const EdgeInsets.only(left: 20, right: 20),
                      child: Row(
                        children: [
                          Expanded(
                            flex: 3,
                            child: TextField(
                              controller: widget.todoTextEditingController,
                              maxLines: 1,
                            ),
                          ),
                          Expanded(
                            flex: 1,
                            child: TextButton(
                              onPressed: () {
                                print('add');
                                //_.todoArray.add(TodoListTile(widget.todoTextEditingController.value));
                                if (widget.todoTextEditingController.text != '') {
                                  _.addItem(widget.todoTextEditingController.text);
                                  widget.todoTextEditingController.text = '';
                                  _.update();
                                }
                              },
                              child: const Text(
                                'Add',
                                style: TextStyle(color: Colors.white),
                              ),
                              style: ButtonStyle(
                                backgroundColor:
                                    MaterialStateProperty.resolveWith((states) {
                                  if (states.contains(MaterialState.pressed)) {
                                    return Colors.orange;
                                  } else {
                                    return Colors.yellow;
                                  }
                                }),
                                overlayColor: MaterialStateProperty.resolveWith(
                                    (states) => Colors.redAccent),
                              ),
                            ),
                          )
                        ],
                      ),
                    ),
                  ),
                  const Divider(
                    thickness: 1,
                    color: Colors.grey,
                  ),
                  Flexible(
                    flex: 8,
                    child: ListView.builder(
                      itemBuilder: (context, index) {
                        return _.todoArray[index];
                      },
                      // itemCount: widget.todoController.todoArray.length,
                      itemCount: _.todoArray.length,
                    ),
                  )
                ],
              ),
            );
          }),
    );
  }
}
//todo_controller.dart
import 'package:get/get.dart';
import 'package:todo/view/todo_list_tile.dart';

class TodoController extends GetxController {
  List<TodoListTile> todoArray = <TodoListTile>[].obs;

  //item 등록
  void addItem(String item) {
    todoArray.add(TodoListTile(itemText: item));
    update();
  }

  //item 삭제
  void deleteItem(String item) {
    for (int i = 0 ; i < todoArray.length; i++) {
      if (todoArray[i].itemText == item){
        todoArray.removeAt(i);
        break;
      }
    }
    update();
  }
}
728x90
반응형