ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [FLUTTER] 리펙토리(Refactory)
    Flutter 2023. 4. 7. 00:51
    동작의 변경 없이 코드를 정리하는 과정

    Dialog를 띄우는 로직()이 너무 길어서 보기 힘드므로, 해당 로직을 별도의 함수로 분리 시켜보는 작업

    • HomePage 일부 showDialog
    showDialog(
                            context: context,
                            builder: (context) {
                              // 경고창 생성
                              return AlertDialog(
                                title: Text("정말로 삭제하시겠습니까?"),
                                actions: [
                                  // 취소 버튼
                                  TextButton(
                                    onPressed: () {
                                      Navigator.pop(context);
                                    },
                                    child: Text("취소"),
                                  ),
                                  // 확인 버튼
                                  TextButton(
                                    onPressed: () {
                                      setState(() {
                                        // index에 해당하는 항목 삭제
                                        bucketList.removeAt(index);
                                      });
                                      Navigator.pop(context);
                                    },
                                    child: Text(
                                      "확인",
                                      style: TextStyle(color: Colors.pink),
                                    ),
                                  ),
                                ],
                              );
                            },
                          );

     

    1. showDeleteDialog 메소드(함수)로 분리

    : showDialog를 클릭한 뒤 왼쪽에 전구(💡) 아이콘을 선택하고, Extract Method를 선택

    • 메소드(함수)의 이름을 입력하라고 뜨면 showDeleteDialog라고 입력한 뒤 엔터를 누르고 저장

    • 코드 하단으로 내려가보면 showDeleteDialog함수가 생성된 것을 볼 수 있음!

     

    • 전체 결과 코드
    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          debugShowCheckedModeBanner: false,
          home: HomePage(),
        );
      }
    }
    
    /// 버킷 클래스
    class Bucket {
      String job; // 할 일
      bool isDone; // 완료 여부
    
      Bucket(this.job, this.isDone); // 생성자
    }
    
    /// 홈 페이지
    class HomePage extends StatefulWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    // 상태 클래스
    class _HomePageState extends State<HomePage> {
      List<Bucket> bucketList = []; // 전체 버킷리스트 목록
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("버킷 리스트"),
          ),
          body: bucketList.isEmpty
              ? Center(child: Text("버킷 리스트를 작성해 주세요."))
              : ListView.builder(
                  itemCount: bucketList.length, // bucketList 개수 만큼 보여주기
                  itemBuilder: (context, index) {
                    Bucket bucket = bucketList[index]; // index에 해당하는 bucket 가져오기
                    return ListTile(
                      // 버킷 리스트 할 일
                      title: Text(
                        // bucket이 할일을 job이라는 속성이 가지고 있다.
                        bucket.job,
                        style: TextStyle(
                          color: bucket.isDone ? Colors.grey : Colors.black,
                          decoration: bucket.isDone
                              ? TextDecoration.lineThrough
                              : TextDecoration.none,
                          fontSize: 24,
                        ),
                      ),
                      // 삭제 아이콘 버튼
                      trailing: IconButton(
                        icon: Icon(CupertinoIcons.delete),
                        onPressed: () {
                          // 삭제 버튼 클릭시
                          // print('$bucket : 삭제하기');
                          showDeleteDialog(context, index);
                        },
                      ),
                      onTap: () {
                        // 아이템 클릭시
                        // print('$bucket : 클릭 됨');
                        setState(() {
                          // Toggle 기능
                          bucket.isDone = !bucket.isDone;
                        });
                      },
                    );
                  },
                ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.add),
            onPressed: () async {
              // + 버튼 클릭시 버킷 생성 페이지로 이동
              String? job = await Navigator.push(
                context,
                MaterialPageRoute(builder: (_) => CreatePage()),
              );
              // print(job);
              if (job != null) {
                // 화면 갱신 명령어 필수
                setState(() {
                  // 생성자를 호출해서 bucket 클래스의 인스턴스를 호출
                  Bucket newBucket = Bucket(job, false);
                  // job을 그대로 넣을 수 없음 (String 형이므로, 우리가 선언한건 Bucket 구조체)
                  bucketList.add(newBucket); // 버킷 리스트에 추가
                });
              }
            },
          ),
        );
      }
    
      void showDeleteDialog(BuildContext context, int index) {
        showDialog(
          context: context,
          builder: (context) {
            // 경고창 생성
            return AlertDialog(
              title: Text("정말로 삭제하시겠습니까?"),
              actions: [
                // 취소 버튼
                TextButton(
                  onPressed: () {
                    Navigator.pop(context);
                  },
                  child: Text("취소"),
                ),
                // 확인 버튼
                TextButton(
                  onPressed: () {
                    setState(() {
                      // index에 해당하는 항목 삭제
                      bucketList.removeAt(index);
                    });
                    Navigator.pop(context);
                  },
                  child: Text(
                    "확인",
                    style: TextStyle(color: Colors.pink),
                  ),
                ),
              ],
            );
          },
        );
      }
    }
    
    /// 버킷 생성 페이지
    class CreatePage extends StatefulWidget {
      const CreatePage({Key? key}) : super(key: key);
    
      @override
      State<CreatePage> createState() => _CreatePageState();
    }
    
    class _CreatePageState extends State<CreatePage> {
      // TextField의 값을 가져올 때 사용합니다.
      TextEditingController textController = TextEditingController();
    
      // 경고 메세지
      String? error;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("버킷리스트 작성"),
            // 뒤로가기 버튼
            leading: IconButton(
              icon: Icon(CupertinoIcons.chevron_back),
              onPressed: () {
                Navigator.pop(context);
              },
            ),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              children: [
                // 텍스트 입력창
                TextField(
                  controller:
                      textController, // TextField와 TextEditingController를 연결해 줍니다.
                  autofocus: true,
                  decoration: InputDecoration(
                    hintText: "하고 싶은 일을 입력하세요",
                    errorText: error,
                  ),
                ),
                SizedBox(height: 32),
                // 추가하기 버튼
                SizedBox(
                  width: double.infinity,
                  height: 48,
                  child: ElevatedButton(
                    child: Text(
                      "추가하기",
                      style: TextStyle(
                        fontSize: 18,
                      ),
                    ),
                    onPressed: () {
                      // 추가하기 버튼 클릭시
                      String job =
                          textController.text; // textController로부터 현재 입력되어있는 값을 가져옴
                      // print(job);
                      if (job.isEmpty) {
                        setState(() {
                          // error 변수의 값이 바뀌는 경우 화면을 갱신
                          error = "내용을 입력해주세요."; // 내용이 없는 경우 에러 메세지
                        });
                      } else {
                        setState(() {
                          error = null; // 내용이 있는 경우 에러 메세지 숨기기
                        });
                        // 뒤쪽 화면으로 넘기고 싶은 변수를 두번째 파라미터에 넣어주면 됨.
                        Navigator.pop(context, job); // job 변수를 반환하며 화면을 종료
                      }
                    },
                  ),
                ),
              ],
            ),
          ),
        );
      }
    }

     

    [버킷리스트 CRUD 구현이 궁금하다면? 아래 GitHub 참고]

    https://github.com/Eunice991217/Flutter-ToyProject/tree/main/bucket_list

     

    GitHub - Eunice991217/Flutter-ToyProject: Flutter Project Practice

    Flutter Project Practice. Contribute to Eunice991217/Flutter-ToyProject development by creating an account on GitHub.

    github.com

     

Designed by Tistory.