카테고리 없음

flutter listview builder constraintsError - Expanded vs Flexible

햎피 2022. 6. 22. 10:17
반응형

flutter에서 listview builder를 이용해서 연속된 항목들을 보여주는 경우가 많다.

하지만 listview builder의 크기때문에 여러 에러들이 난다.

에러가 났던 코드들과 그 이유에 대해서 설명해보겠다.

 

대표적인 에러가 constraintsError이다.

에러 메시지가 이렇게나 길었다..

 

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 shrinkwrap 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 shrinkwrap 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 shrinkwrap the children rather than expanding to fit the maximum constraints provided by the parent.
If this message did not help you determine the problem, consider using debugDumpRenderTree():
  https://flutter.dev/debugging/#rendering-layer
  http://api.flutter.dev/flutter/rendering/debugDumpRenderTree.html
The affected RenderFlex is:
  RenderFlex#27935 relayoutBoundary=up15 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE(creator: Column ← MediaQuery ← Padding ← SafeArea ← _SingleChildViewport ← IgnorePointer-[GlobalKey#c6de9] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#33474] ← Listener ← _ScrollableScope ← ⋯, parentData: offset=Offset(0.0, 0.0) (can use size), constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=Infinity), size: MISSING, direction: vertical, mainAxisAlignment: start, mainAxisSize: max, crossAxisAlignment: center, verticalDirection: down)
The creator information is set to:
  Column ← MediaQuery ← Padding ← SafeArea ← _SingleChildViewport ← IgnorePointer-[GlobalKey#c6de9] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#33474] ← Listener ← _ScrollableScope ← ⋯
The nearest ancestor providing an unbounded width constraint is: _RenderSingleChildViewport#7a2d5 relayoutBoundary=up13 NEEDS-LAYOUT NEEDS-PAINT NEEDS-COMPOSITING-BITS-UPDATE:
  needs compositing
  creator: _SingleChildViewport ← IgnorePointer-[GlobalKey#c6de9] ← Semantics ← Listener ← _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#33474] ← Listener ← _ScrollableScope ← _ScrollSemantics-[GlobalKey#ed6c6] ← NotificationListener<ScrollMetricsNotification> ← RepaintBoundary ← CustomPaint ← ⋯
  parentData: <none> (can use size)
  constraints: BoxConstraints(0.0<=w<=411.4, 0.0<=h<=673.4)
  size: MISSING
See also: https://flutter.dev/layout/
If none of the above helps enough to fix this problem, please don't hesitate to file a bug:
  https://github.com/flutter/flutter/issues/new?template=2_bug.md

 

해석을 해보자면 높이 제약이 없어서 발생한 에러이다.

parent가 Column인 경우에, 높이 제한을 주지 않는다. (높이가 무한함)

그런데 이때 child에 Expanded를 사용할 경우 세로방향의 나머지 공간을 채우기 위해서 child가 확장된다.

이 두개를 같이 사용할 수 없다.

mainAxisSize를 MainAxisSize.min으로 설정하고, Expanded대신 Flexible을 사용한다.

이렇게 하면 스스로 크기를 조정 할 수 있고, parent가 Column의 최대 제약 조건을 안따른다.

(덧붙여 설명하자면, MainAxisSize.min은 크기만큼 차지, MainAxisSize.max는 남은 영역을 모두 사용) 

 

 

에러가 났던 코드 :

일단 코드 설명을 하자면, MonthScreen에서 Scaffold를 생성해주고,

Eventlist에서 listview를 조절해준다.

listview() 함수가 listview.builder를 불러오는 것이고, 리스트뷰를 Expanded로 감싸고,  Expanded를 Container로 감싸주었다.

class MonthScreen extends StatelessWidget {
  const MonthScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        resizeToAvoidBottomInset: false,
        body: SingleChildScrollView(
            child: SafeArea(
                child: Column(
          children: [
            Eventlist(),
          ],
        ))));
  }
}
class Eventlist extends StatelessWidget {
  late calendarModel calendarmodel;
  late DiaryDailyQuillModel quillController;

  Eventlist({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    calendarmodel = Provider.of<calendarModel>(context);
    quillController = Provider.of<DiaryDailyQuillModel>(context);

    return Container(child: Expanded(child: listview()));
class listview extends StatelessWidget {
  listview({Key? key}) : super(key: key);
  late calendarModel calendarmodel;
  late DiaryDailyQuillModel quillController;

  @override
  Widget build(BuildContext context) {
    calendarmodel = Provider.of<calendarModel>(context);
    quillController = Provider.of<DiaryDailyQuillModel>(context);

    return ListView.builder(
        physics: AlwaysScrollableScrollPhysics(),
        shrinkWrap: false,
        itemCount: calendarmodel.selectedEvents.length,
        itemBuilder: (context, index) {
          return Container(
          ...
          );

 

Column에

mainAxisSize :MainAxisSize.min,을 추가해주고,

Expanded를 Flexible로 바꿔주고,

 

shrinkWrap : true로 바꿔주었다.

 

그런데 scroll이 되지 않는다.

scroll과 관련해서는 다음 포스팅에서 다루겠다.

반응형