2024. 12. 4. 18:18ㆍ같이 공부합시다 - Flutter/Flutter로 To-Do 앱 만들기
두둥 !
이번엔 이전 내용에 이어지는 기능입니다.
이제 우리는 완료/미완료 체크를 구분할 수 있으므로,
그에 따른 필터 기능을 추가할 수 있습니다 !
좋아요 ! 멋집니다 !
우리 많이 왔네요 : )
이제 이름을 좀 바꿔 봅시다.
대부분 기능 추가에 따른 챕터가 생겼으니까,
할 일 목록입니다. 가 아닌
기능 추가 목록입니다. 😁
3 . 화면에 할 일 리스트 표시.4 . 할 일 삭제 기능 추가5 . 데이터 저장 추가6 . 항목 완료 체크 기능 추가
7 . 완료/미완료 분리 표시 및 필터 기능 추가
8 . 할 일 목록 수정 기능 추가
9 . 완료된 항목을 자동으로 삭제하는 옵션 추가
…
자, 오늘의 주요 기능은 ‘필터링’입니다.
필터링 기능을 구현하기 위한 오늘의 할 일 입니다 : )
- 팝업 메뉴 버튼 추가하기
- 필터 상태값 만들기
- PopupMenuButton 메뉴에 필터 상태값 추가
- 필터된 리스트를 담아둘 수 있는 변수 만들기
- _getFilteredTodos() 메서드 만들기
- 앱 화면에 필터된 리스트 보여주기
메뉴 버튼을 하나 만들어서 필터링 해봅시다 : )
<필터링 이미지>

1) 팝업 메뉴 버튼 추가하기
필터링 할 수 있는 메뉴는 AppBar
그러니까 To-Do List 제목이 있는
위치에 메뉴 버튼을 추가해 봅시다.
<기존 AppBar>

<PopupMenuButton 추가>

1-1) actions : [ PopupMenuButton () ]
AppBar 의 속성인 actions 에,
PopupMenuButton 을 추가합시다.
( actions 속성에서는 정말 많은 기능이 있어요. 😅 )
이전에 FloatingButton 만들 때가 엊그제 같은데,
벌써 시간이 좀 지났네요 (ㅎ)
2024.11.23 - [Develog/Flutter] - To-Do List 앱 Step 2-0. 플로팅버튼 띄우기
To-Do List 앱 Step 2-0. 플로팅버튼 띄우기
서론이 너무 길었다.이제 드디어 기능을 넣어 볼 차례다. 두근두근 거리는구만. 구현하려는 내용은 다음과 같다.1. 화면 오른쪽 아래에 “+ (할 일 추가)” 플로팅 버튼 만들기.2. 플로팅 버튼을
steadybuilder.tistory.com
1-2) itemBuilder: (context) => [ ]
여기에서는 다이얼로그와 유사한
itemBuilder 속성이 필요합니다.
(다이얼로그에서는 builder 속성 사용)
2024.11.24 - [Develog/Flutter] - To-Do List 앱 Step 2-1. 플로팅버튼 > 다이얼로그 기본 호출 구조
To-Do List 앱 Step 2-1. 플로팅버튼 > 다이얼로그 기본 호출 구조
[ 만들어 보려는 내용 ]1 . 화면 오른쪽 아래에 “+ (할 일 추가)” 플로팅 버튼 만들기.2-1. 플로팅 버튼을 눌렀을 때 다이얼로그가 열리고, 사용자가 할 일을 입력할 수 있음.2-2. ‘취소’ 텍스트
steadybuilder.tistory.com
builder 나 itemBuilder 는 앱 화면 안에서
일정 부분의 팝업을 만들어주는 역할을 합니다.
itemBuilder 또한
BuildContext context 를
매개변수로 받아서,
화면에 뿌려줄 메뉴 항목 리스트를
만들어 줍니다.
참고로, 플러터는 타입 정보를 많이 생략하기 때문에,
(context) 로만 사용해도 오류가 발생되지 않아요.
이 [ ] 안에는 눈으로 볼 메뉴 항목을 설정하면 됩니다.
<PopupMenuButton 추가 결과>

전체 보기 외에 ‘완료 보기’ ,
그리고 ‘미완료 보기’ 도 추가해야겠죠 ?
<PopupMenuButton 메뉴 추가>

좋아요 ! 그럴듯해졌죠 ?
메뉴만 만들어진 것 뿐,
아직은 동작하지 않습니다.
이제 동작되도록 해야죠 !
2) 필터 상태값 만들기
필터를 하기 위해서는,
기준이 되는 플래그 값이 필요합니다.
즉, 필터 상태값을 말하죠.
앞에서 만든 PopupMenuButton 메뉴 중 하나를
선택했을 때, 필터 상태값이 바뀔 수 있도록 하는거죠.
<필터 상태값 만들기>

_todoList 완료 상태값은
isCompleted 의
true / false 로 구분했죠.
필터는 completed(완료) , active(미완료) ,
all(전체)로 구분합시다.
_filter 변수에 초기값은
all(전체)로 설정할게요.
3) PopupMenuButton 메뉴에 필터 상태값 추가
아까 만들어 둔 팝업 메뉴에서,
메뉴를 터치했을 때 필터 상태값이 변하도록 해봅시다.
그럴려면 각 메뉴 별 상태에 대한 값을 가져야겠죠.
<PopupMenuButton 메뉴에 필터 상태값 추가>

🔸PopupMenuButton(value…
각 메뉴에 value 로 구분값을 주었습니다.
value 를 child 뒤에 두려니 경고가 뜨네요,
앞으로 옮기라고 (ㅎ) 뭐 , 권장 규격에 맞춥시다.
🔸onSelected:
테스트를 위해 메뉴를 선택했을 때마다
콘솔에 남기도록 했습니다.
하나씩 메뉴를 눌러보면
value 값을 잘 받아오는 것을 볼 수 있습니다.
굿굿 !
이제 이 value 값이 필터 상태값으로
만들어 둔 _filter 를 바꾸면 되겠군요.
<PopupMenuButton의 메뉴 클릭 시 필터 상태값 변경>

🔸setState()
사용자가 PopupMenuButton의 메뉴를 클릭했을 때,
실시간으로 value의 값이 _filter 에 적용되어야만,
이후에 body 에서 실시간으로
출력되는 항목을 변경할 수 있어요.
이제 우리는 필터 메뉴에서 상태값까지
실시간으로 변경할 수 있도록 만들었어요.
이제 뭐하면 될까요 ?
맞습니다. 필터에 따라 화면 뿌려주면 되겠죠 !
4) 필터된 리스트를 담아둘 수 있는 변수 만들기
자, 여기서부터는 집중해서 따라오셔야 합니다.
생각보다 복잡하거든요.

아시죠? 그래도 가봅시다 !
현재 화면에 뿌려주도록 되어 있는 값은
final todoItem = _todoList[index]; 입니다.
List 인 _todoList 의 index,
그러니까 0,1,2 .. 에 따라 저장된 정보를 가져오죠.
지금 제 _todoList 는 이렇습니다.
<스테디빌더의 _todoList>

여기에서 _todoList[0] 을 출력하면,
{task: 1. _todoList 를 Map 형태로 변경하기, isCompleted: true},
값을 확인할 수 있습니다.
그리고 현재 우리 앱은 이렇게 _todoList 에 있는
모든 할 일이 화면에 뿌려지는 중이죠.
하지만 이제는 body 에 필터가 된
리스트를 불러올 필요가 있게 되었습니다.
이제 필터 상태값(_filter)에 따라서
필터링된 리스트를 담아둘 수 있도록 만들어 봅시다.
<필터된 리스트를 담아둘 수 있는 변수 만들기>

build () 아래 바로 필터된 리스트를
받아올 수 있도록 했습니다.
음? 왜 body 에 있지 않고 여기에 있냐구요?
맞습니다. 기존에 있던 위치랑 다르죠.
<기존에 할 일 목록을 뿌려주는 코드>

<기존 위치와 현재 위치 차이>

이유는 이후에 알려드리겠지만,
body 속성에서도 필터된 리스트가
필요하기 때문입니다.
body: _todoList.isEmpty
코드의 조건을 필터된 항목의 리스트가
비어있는지를 체크해야 하기 때문이예요.
ListView.builder 안에 지역변수로 있다면
body 속성에서는 사용하지 못할테니까요.
자자, 지금 이해가 안된다면 일단 넘어갑시다.
계속 보다보면 이해됩니다 : )

_getFilteredTodos() 메서드를 호출했으니,
이제 이 메서드를 만들어 볼까요?
5) _getFilteredTodos() 메서드 만들기
<_getFilteredTodos() 메서드 만들기>

_filter 값이 ‘active’ 이면 완료되지 않은 할 일이죠.
_todoList.where( ) 메서드는
List 클래스에 포함된 메서드로
특정 조건을 만족하는 항목만
걸러내는 역할을 합니다.
여기에서 (item) 은 _todoList 의 각 요소를 의미하고,
toList() 메서드를 통해 새로운 리스트로 변환합니다.
where 메서드의 반환값은
List 가 아닌 Iterable 이기 때문에,
리스트로 변환이 필요합니다.
정리하면,
_todoList 항목(item) 중에서
isCompleted 의 값이 false ,
그리고 다음 줄은 true 인 것을 찾아서 ,
리스트로 변환하여
새로운 리스트를 얻게 되는거죠 !
if else 에 걸리지 않는다면
자연스레 all 이 됩니다.
노파심에 하나 덧붙이자면,
where 메서드는 조건이
true 인 항목만 필터링 합니다.
따라서, !item[’isCompleted’] 코드는
항목중에 isCompleted 가
false 인 항목만을 필터링 하는거죠.
좋습니다.
여기까지 이해 됐어요 !
6) 앱 화면에 필터된 리스트 보여주기
드디어 마지막 작업입니다 !
조금만 더 힘을 내세요 : )

final filteredTodos = _getFilteredTodos();
방금 만들어 둔 메서드를 통해,
이제 필터 상태값 value 에 따라
완료 , 미완료 , 전체 리스트를
filteredTodos 에
담아둘 수 있게 되었어요.
좋습니다 !
이제 body 에서 직접 _todoList 의
항목을 뿌려주는 부분을,
전부 filteredTodos 로 바꿔줘야 합니다.
<filteredTodos 로 변경하기>

6-1) body: filteredTodos.isEmpty
전체 항목이 아닌 필터된 항목이
비어있을 때로 조건을 바꾸었습니다.
6-2) itemCount: filteredTodos.length
전체보기, 완료보기, 미완료보기
모두 필터된 상태로 보여지기 때문에,
itemCount 또한 filteredTodos 를 설정합니다.
6-3) final todoItem = filteredTodos[index]
기존 _todoList 에 접근하던 녀석을
filteredTodos 리스트에 접근하도록 바꿉니다.
이 녀석을 뿌려주게 되죠 : )
6-4) final actualIndex = _todoList.indexOf(todoItem)
actualIndex 는
실제 _todoList 의 값을
변경하기 위해섭니다.
지금의 todoItem 은
필터된 리스트의 인덱스를
가지고 있기 때문이죠.
actualIndex 는
완료 체크나 삭제 시에 사용됩니다.
자, 다 됐습니다 !
이제 마무리 테스트만 남았네요 : )

완료 보기 ! 쾅 !
미완료 보기 ! 쾅 !
전체 보기 ! 쾅 !
<오늘의 결과>

굿 !
이 상태에서 미완료 항목의 체크박스를 체크하면 ?
짜잔. 미완료 항목에서는 없어지고
완료 항목에서 확인 가능 !
고생하셨습니다 !
끝 !
'같이 공부합시다 - Flutter > Flutter로 To-Do 앱 만들기' 카테고리의 다른 글
To-Do List 앱 Step 9. 완료된 항목을 자동으로 삭제하는 옵션 추가 (0) | 2024.12.09 |
---|---|
To-Do List 앱 Step 8. 할 일 목록 수정 기능 추가 (0) | 2024.12.06 |
To-Do List 앱 Step 6. 항목 완료 체크 기능 추가 (0) | 2024.12.03 |
To-Do List 앱 Step 5. 데이터 저장 (0) | 2024.12.02 |
To-Do List 앱 Step 4. 할 일 삭제 기능 추가 (0) | 2024.11.28 |