Programming/Flutter

[Flutter] overflow 처리하기

stein 2022. 1. 28. 00:06

다음과 같은 flutter 코드가 있다.

 Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(bottom: 4.0),
          child: Row(
            children: [
              Text(
                category,
                style: TextStyle(fontSize: 12),
              )
            ],
          ),
        ),
        Row(
          children: [
            Text(
              title,
              style: TextStyle(fontSize: 24),
            ),
          ],
        )
      ],
    );

카테고리와 제목을 표현하는 리스트 항목 컴포넌트이다. 하지만 이를 구현하면

얼마나 Overflowed 되었는지, 어디가 Overflow 되었는지 설명해준다.

음.. css였으면 overflow를 통해서 해결할 수 있었을 텐데, 한 번 넣어보자. 다음 stackoverflow 답변 중 하나를 찾았다.

https://stackoverflow.com/questions/51930754/flutter-wrapping-text

 

Flutter- wrapping text

I want wrap text as text grows. I searched through and tried wrap with almost everything but still text stays one line and overflows from the screen. Does anyone know how to achieve this? Any help...

stackoverflow.com

Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(bottom: 4.0),
          child: Row(
            children: [
              Text(
                category,
                style: TextStyle(fontSize: 12),
                overflow: TextOverflow.ellipsis,
              )
            ],
          ),
        ),
        Row(
          children: [
            Text(
              title,
              style: TextStyle(fontSize: 24),
              overflow: TextOverflow.ellipsis,
            ),
          ],
        )
      ],
    );

overflow 옵션을 Text에 추가해 보았지만 아무런 변화가 없다. 에러문구를 확인해보니 다음과 같다.

 

A RenderFlex overflowed by 41 pixels on the right.

그래서 마찬가지로 위의 stackoverflow 게시글이 검색되어서, 그 첫 번째 답변을 활용해보았다.

Flexible을 사용하라고 하면서, Column, row, Flex와 함께 사용되어야한다고 한다.

어디갔나요

Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Padding(
          padding: const EdgeInsets.only(bottom: 4.0),
          child: Row(
            children: [
              Flexible(
                child: Text(
                  category,
                  style: TextStyle(fontSize: 12),
                ),
              )
            ],
          ),
        ),
        Row(
          children: [
            Flexible(
              child: Text(
                title,
                style: TextStyle(fontSize: 24),
              ),
            ),
          ],
        )
      ],
    );

사라졌다. 그 와중에 overflow는 발생한단다. flex인데 가로 너비가 지정이 안되어서 그런 모양이다. 에러 문구를 확인해보자.

 

RenderFlex children have non-zero flex but incoming width constraints are unbounded.

 

정확히 해석되지는 않지만, width가 정해지지 않은, unbounded 되어서 생기는 것 같다. 해당 에러로 검색해보니 다음과 같은 stackoverflow를 찾았다.

https://stackoverflow.com/questions/57803737/flutter-renderflex-children-have-non-zero-flex-but-incoming-height-constraints

 

Flutter: "RenderFlex children have non-zero flex but incoming height constraints are unbounded"

I want to have a ListView inside another widget when I wrap FutureBuilder in a Column in order to have a simple Row. I get this error: The following assertion was thrown during performLayout(): I/f...

stackoverflow.com

Column에 Expaned를 걸어주거나, 높이를 주라고 한다. 아마 현재 우리 상황에서는 너비를 주는 게 맞겠지. 두 가지 코드 모드 확인해보자.

 

SizedBox(
  width: 200,
  child: Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    children: [
      Padding(
        padding: const EdgeInsets.only(bottom: 4.0),
        child: Row(
          children: [
            Flexible(
              child: Text(
                category,
                style: TextStyle(fontSize: 12),
              ),
            )
          ],
        ),
      ),
      Row(
        children: [
          Flexible(
            child: Text(
              title,
              style: TextStyle(fontSize: 24),
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      )
    ],
  ),
);

overflow 옵션의 효과. ellipsis(좌), none(우)

드디어 overflow 되지 않고 잘 출력된다. 이때, 처음 설정한 text의 Overflow 옵션이 작동하는 걸 볼 수 있다.

Expanded로 적용해보자.

Expanded(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.only(bottom: 4.0),
            child: Row(
              children: [
                Flexible(
                  child: Text(
                    category,
                    style: TextStyle(fontSize: 12),
                  ),
                )
              ],
            ),
          ),
          Row(
            children: [
              Flexible(
                child: Text(
                  title,
                  style: TextStyle(fontSize: 24),
                ),
              ),
            ],
          )
        ],
      ),
    );

잘 출력된다.

기기별로 화면 사이즈가 다르기 때문에, sized보다 expanded를 더 많이 쓰지 않을까 생각한다(반응형).

 


결론

expanded(

    column(

         flexible(

               widget()

          )

     )

)

로 사용하면 되겠다.

 

에러 문구를 차분히 하나씩 따라가면 매우 쉬운 문제였는데, 기존에 사용하던 코드들과 여러 예제들을 한꺼번에 사용하려다 보니 엄청 헤매었다.

 

처음 사용하는 프레임워크, 언어일 경우에는 꼭 서두르지 말기로 하자.