최근에 플러터로 개발하면서 A RenderFlex overflowed by ...
에러가 많이 발생했어요.
원인은 Page 역할을 하는 큰 위젯에 Scaffold를 사용하고 있고 body 파라미터에 Column을 사용해서 여러 위젯이 들어가 있었어요. 보통 Column에 코드의 가독성과 재사용성을 위해 어떤 위젯들은 파일을 생성하고 위젯을 만드는데요. 어떤 위젯은 Expanded로 감싼 Column을 가진 상황이었어요. 저 에러가 발생하기 전의 계층 구조는 아래와 같아요.
Scaffold
SafeArea
Column
Padding
SizedBox
Expanded
Form
Column
Expanded
Padding
Column
ListTile
SizedBox
Column
TextFormField
SizedBox
Text
SizedBox
Wrap
ChoiceChips
Container
FilledButton
그런데 여기서 가상 키보드가 등장하면서 문제가 발생했어요. height가 작은 경우에 Wrap 위젯이 감싸고 있는 Chip 위젯들 중 아래에 있는 곳과 FilledButton이 서로 충돌하는 이슈였어요.
그때의 상황을 비슷하게 구현했던 예제
그리고 이 문제를 해결하는 방법으로 제가 원하는 건, 기존에 다음 버튼이 키보드 위로 잘 올라오고 있었으니, 가상 키보드가 올라올 때 Chip들만 스크롤할 수 있게 되면 좋겠다고 생각했어요.
많은 예제들을 찾아봤지만 대부분 Scaffold body에 SingleChildScrollView로 감싸고 reverse: true
로 주면 해결된다, Scaffold에 resizeToAvoidBottomInset: false
를 주면 된다고 말했지만 이 방법들은 제 상황에서 문제가 있었어요.
SingleChildScrollView로 body를 감싸는 경우는 전체 영역이 스크롤되기 때문에 고정하고 싶은 영역도 같이 스크롤되는 문제가 있었어요. 원하는 부분만 스크롤되길 원했기 때문에 지금 상황에서는 좋은 방법이 아니라고 생각되었어요.
resizeToAvoidBottomInset: false
를 이용하는 경우는 FilledButton이 가상 키보드에 가려서 보이지 않게 돼요. 그러면 Scaffold에 bottomSheet를 이용해야 하는데 body에 SafeArea를 준 상황인데도 아이폰에서는 하단에 위치한 Home indicator
가 있는 위치에 버튼이 생겨 SafeArea가 적용되지 않았어요. Padding을 주면 해결되지만 그러면 가상 키보드가 올라올 때도 그만큼 패딩이 붙어서 만족스럽지 않았어요.
그런데 여기서 Chip 위젯들을 스크롤되기 위해 Layout 위젯들을 추가했는데 파일이 여러 개가 연결되어 있고 Column에 Column이 들어있는 상황이라 뭘 추가해서 테스트할 때마다 RenderFlex overflow 관련 오류가 나서 코딩하기 정말 힘들었어요.
저한테 이 오류가 발생했던 가장 큰 이유로, Column 내부에서 Expanded로 감싼 Column이 있는데 그 Column에서 또 Expanded를 사용하는 Column이 있었어요. 이 Layout 구성을 제대로 이해하지 않고, 고려하지 않고 만들다 보니 오류의 원인을 찾기 어려웠어요. 결국 기존 위젯들을 주석 처리하고 간단한 예제를 만들어 가면서 레이아웃을 다시 구성했어요.
Expanded는 위젯은 Row, Column, Flex 같은 위젯에서 그 위젯이 갖는 중심축을 늘릴 수 있는 길이만큼 늘릴 때 사용하는 위젯이에요.
Row, Column, Flex의 자식으로써 사용되어야 해요. 다른 자식들이 특정 부분을 채우면 Expanded 위젯이 남은 부분을 전부 채워요.
이런저런 시도를 하다가 원하는 Chip 위젯들만 스크롤 되면서 RenderFlex overflow가 발생하지 않는 방법을 찾았어요.
Scaffold
SafeArea
Column
Padding
SizedBox
Expanded
Form
Column
Padding
Column
ListTile
SizedBox
Column
TextFormField
SizedBox
Text
SizedBox
Expanded
SingleChildScrollView
Wrap
ChoiceChips
Container
FilledButton
이것만이 방법은 아니겠지만, 제 상황에서는 Column 내부에서 특정 영역을 스크롤 되게 만들려면 Expanded와 SingleChildScrollView 위젯을 사용하면 돼요.
I'm selfish, impatient and a little insecure. I make mistakes, I am out of control and at times hard to handle. But if you can't handle me at my worst, then you sure as hell don't deserve me at my best.
— Marilyn Monroe