Flutter 개발일지 day 13
unfocus 구현
입력을 하려면 키보드가 필요하고, 키보드가 뜨면 당연히 따라오는게 focus 개념이다. 우리가 어떤 TextField를 클릭하면 그 Field를 focus하게 되고, focus하게 되면 키보드를 띄운다. 반대로, focus가 풀리면 키보드가 사라지게 된다. 이를 이용해서 키보드 out focus를 (키보드 내리기 버튼을 눌러야 하는게 아니라)좀 더 편하게 할 수 있게 하려고 한다.
우리가 원하는 기능은 키보드가 띄워져 있는 상황에서(즉 특정 field에 focus된 상황에서) 아무 영역이나 tap하면 키보드를 내리는 것이었다. 따라서, 그 어떤 곳이라도 tap(=ontap)하면 키보드를 내릴 수 있게(=unfocus) 해야한다. 가장 좋은 방법은 최상위 계층인 Scaffold에 GestureDetector을 씌우는 거다. scaffold는 흰 화면 전체를 띄우는, 가장 근본이 되는 widget이기 때문에 여기다가 gesture를 주면 화면 그 어디를 눌러도 gesture를 인식할 수 있다.
1
2
3
4
GestureDetector(
onTap: () => FocusManager.instance.primaryFocus?.unfocus(),
child: Scaffold(...)
)
요렇게 쓰면 아주 편리하게 화면 아무 곳이나 tap하면 어디든 간에 focus 되어있는 곳에서 unfocus 된다.
TextFormField 수정
어제는 SliverToBoxAdapter에서 onSaved까지만 넣었었다. onSaved를 작동시키려면 매번 key를 통해 호출해야하기 때문에, 키보드의 완료 버튼을 누르면 실행될 수 있도록 onFieldSubmitted 메소드를 집어 넣었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
onFieldSubmitted: (text) {
if(text!.isEmpty) {
FocusManager.instance.primaryFocus?.unfocus();
return;
}
String scheduleDate = Provider.of<Cursor>(context, listen: false).returnAsString();
if(box.containsKey(scheduleDate)) {
List tmp = box.get(scheduleDate)!;
tmp.add(ScheduleClass(name: text!, date: DateTime.now()));
box.put(scheduleDate, tmp);
}
else {
List tmp = [ScheduleClass(name: text!, date: DateTime.now())];
box.put(scheduleDate, tmp);
}
},
-
최초 if문 : 아무것도 안넣고(null) 그냥 엔터 때렸을 경우에 그냥 아무일도 없던 것처럼 해주기 위한 filtering이다. 엔터(=submit) 눌렀을 때 isEmpty == true 이면 키보드를 unfocus해주고 그냥 onFieldSubmitted 함수를 종료한다.
-
이후 : 그 이후는 예전에 onSaved에서 했던 동작과 동일하다. 입력받은 text를 ScheduleClass에 저장하고, 그 ScheduleClass를 hive box에 넣어준다.
-
번외 : 여기에는 안썼지만, TextFormField에 child를 넣기 전에 key에다가 내가 정의한 key를 넣어준다. 그래야지만 onSaved 및 validator 메소드를 쓸 수 있다. 나는 GlobalKey를 전역변수로 선언하고 여기서 호출 했다.
배운점
-
onSaved 메소드는 생각보다 쓰기 까다롭다. 매번 key를 통해 validator을 통과한 이후에만 state가 존재하기 때문에, save 한 번 하려면 두줄씩 뭐가 딸려온다. 그래서 일단 여기서는 onFieldSubmitted를 썼고, 나중에 어찌어찌 잘 필터링해서 그냥 key를 안 써버리는 방법도 생각중 이다.
-
focus - unfocus 개념은 (아직까지는) 생각보다 쉽다. 처음에는 “키보드를.. 어떻게.. 내리지..?” 싶었다. 완전히 no idea라서 키보드와 관련된 인자부터 찾아야하나 어카지 싶었는데 다행히 flutter에 focus라는 훌륭한 개념이 있어서인지 쉽게 해결할 수 있었다. “뭔가를 누르면 focus->키보드 띄움”이라니.. 참 직관적이라서 좋다. 확실히 플젝을 하고 삽질을 하다보니까 기본기가 많이 느는 느낌이다!