상황에 따라 조금씩 에러메시지는 다를 수 있겠으나, 내가 만난 에러는 다음과 같다.
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
When a column is in a parent that does not provide a finite height constraint, for example if it is in a vertical scrollable, it will try to shrink-wrap its children along the vertical axis. Setting a flex on a child (e.g. using Expanded) indicates that the child is to expand to fill the remaining space in the vertical direction.
These two directives are mutually exclusive. If a parent is to shrink-wrap its child, the child cannot simultaneously expand to fit its parent.
Consider setting mainAxisSize to MainAxisSize.min and using FlexFit.loose fits for the flexible children (using Flexible rather than Expanded). This will allow the flexible children to size themselves to less than the infinite remaining space they would otherwise be forced to take, and then will cause the RenderFlex to shrink-wrap the children rather than expanding to fit the maximum constraints provided by the parent.
코드를 간략히 표현하면 다음과 같다.
WriteDiaryPage
└─ Scaffold
├─ AppBar
│ └─ BackButton
└─ Padding
└─ SingleChildScrollView
└─ Column
├─ Text ("Step 1")
├─ SizedBox (height: 8)
├─ Text ("오늘 있었던 일을 작성주세요")
├─ SizedBox (height: 16)
├─ TextField
│ └─ InputDecoration
└─ Expanded
└─ Align
└─ ElevatedButton
└─ Text ('완료')
문제정의는 에러 메시지를 보면 할 수 있다.
RenderFlex children have non-zero flex but incoming height constraints are unbounded.
RenderFlex의 자식들에게는 0이 아닌 flex 값이 있지만, 부모로부터 받은 높이 제약 조건이 무한합니다.
ListView도 결국 ScrollView
라는 추상클래스를 상속받아서 구현되고 있는 것은 마찬가지이다. 하지만, ListView는 자식 위젯들의 공간에 대해서 자동으로 관리한다. (iOS 에서 UITableView 의 Delegate들 처럼)
덕분에, 사용자는 이미 잘 구현된 높이 계산 객체를 가져다가 사용하기만 하면 된다. 그게 ListView
Widget
개선된 구조를 보면 아래와 같다.
WriteDiaryPage
└─ Scaffold
├─ AppBar
│ └─ BackButton
└─ Padding
└─ ListView <---------- 여기
├─ Text ("Step 1")
├─ SizedBox (height: 8)
├─ Text ("오늘 있었던 일을 작성주세요")
├─ SizedBox (height: 16)
├─ TextField
│ └─ InputDecoration
└─ Flexible
└─ Align
└─ ElevatedButton
└─ Text ('완료')
SwiftUI
에서 사용하던 방식이다. 이 방식으로 해도 무리는 없으나, Flutter
는 조금 다르게, 그 위치를 직접 접근하는 파라미터들이 상당히 많다. Stack 하위에 사용하는 Positioned와 같은 위젯이다.