Single-child layout widgets

김하람·2022년 3월 18일
0

flutter

목록 보기
4/17

CustomSingleChildLayout

childe의 레이아웃을 지정하는 위젯이다.

  • delegate은 child 레이아웃의 constraints를 결정할 수 있다. 또한 child를 어디에 둘지, parent의 크기를 결정한다. 하지만 parent는 child의 크기에 의존하지 않는다.

  • CustomSingleChildLayout은 delegate를 지정해야 한다.

  • 주로 grid를 만들 때 쓰인다.

정리하면, child의 위치, 크기를 결정할 때 사용하는 layout 중 하나이다.


example 1)

const CustomSingleChildLayout({
    Key key,
    @required this.delegate,
    Widget child,
  })

example 2)

Widget single(){
  return CustomSingleChildLayout(delegate: delegate)
}

FittedBox Class

child 또는 내용의 양에 따라 크기가 확장되는 위젯에 의해 오버플로우가 발생되는 경우 FittedBox로 감싸면 전체 크기를 넘지 않게 되며 오버플로우가 방지된다.

alignment를 사용하여 원하는 배열로 나타낼 수 있다.

example)



사용 전)

사용 후)

이처럼 부모에서 주어진 크기 내에 child를 생성할 때 오버플로우가 발생하지 않도록 하기 위해 주로 사용한다.

fittedBox는 부모 크기에 맞춰 child 크기를 조정하는 것이다.
BoxFit.cover를 사용하면 부모 크기에 딱 맞게 child 크기를 조정할 수 있다.

참고) https://medium.com/flutter-community/flutter-widgets-boxes-part-2-the-whole-picture-4bb142f0b1ab


FractionallySizedBox class

FractionallySizedBox class는 상위 부모의 사이즈 비율에 맞게 만드는 것이다.
즉 디자인의 크기가 상대적이어야 할 때 크기를 상위 부모의 사이즈를 바탕으로 비율로 표현하는 것이다.

example)

  • FractionallySizedBox를 사용해서 상위 부모의 사이즈 비율을 지정하여 child의 크기를 정하고 있다.
  • 코드에서 0.7은 70%를 나타낸다. 즉 상위 부모 사이즈의 70%만큼 child를 만들겠다는 의미이다.
  • widthFactor처럼 heightFactor을 사용하여 높이의 비율도 설정할 수 있다.

이처럼 FractionallySizedBox class는 상위 부모의 사이즈 비율로 크기를 지정할 때 사용한다.

IntrinsicHeight class

이름을 보자마자 Intrinsic이 무슨 의미지? 하는 질문이 생겼다.

찾아보니 Intrinsic고유한, 본질적인 이라는 뜻이다.

뜻 그대로 IntrinsicHeight는 child의 고유 높이에 맞춰 child의 크기를 조정하는 위젯이다.

이 위젯은 높이가 제한되지 않고 무한 확장을 시도하는 child를 필요로 할 때 유용하다.

이 위젯이 child에게 전달하는 constraints는 부모의 constraints를 지키기 때문에 만약 constraints가 child의 최대 고유 높이를 포함할 만큼 충분히 크지 않으면 비교적 낮은 높이를 가지게 된다. 반대로, 최소 높이 constraints가 child의 최대 고유 높이보다 크면 비교적 더 많은 높이가 지정된다.

  • 부모의 constraints < child의 고유 높이
    낮은 높이를 가지게 된다.
  • 부모의 constraints > child의 고유 높이
    높은 높이를 가지게 된다.

즉, child는 부모의 constraints를 따르는데, constraints가 존재하지 않는 경우가 있다. 이 때 부모의 constraints와 child의 고유 높이 사이의 관계에 대한 것이다.

가능한 사용하지 않는 것을 추천한다.

<사용 전>

<사용 후>


IntrinsicWidth class

바로 이전에 IntrinsicHeight class에 대해 다루었다.
height가 있으니 width도 존재한다.

IntrinsicHeight class와 거의 비슷한 내용이다.
위 설명에서 height를 width로 바꿔서 이해하면 된다.


이 위젯은 너비가 제한되지 않고 무한 확장을 시도하는 child를 필요로 할 때 유용하다.

이 위젯이 child에게 전달하는 constraints는 부모의 constraints를 지키기 때문에 만약 constraints가 child의 최대 고유 높이를 포함할 만큼 충분히 크지 않으면 비교적 낮은 높이를 가지게 된다. 반대로, 최소 높이 constraints가 child의 최대 고유 높이보다 크면 비교적 더 많은 높이가 지정된다.

  • 부모의 constraints < child의 고유 너비
    낮은 너비를 가지게 된다.
  • 부모의 constraints > child의 고유 너비
    높은 너비를 가지게 된다.

즉, child는 부모의 constraints를 따르는데, 이 때 부모의 constraints와 child의 고유 너비 사이의 관계에 대한 것이다.

이 class 또한 가능한 사용하지 않는 것을 추천한다.

<사용 후>

(사진출처: https://bsscco.github.io/posts/flutter-layout-widgets/)


LimitedBox class

이 위젯은 child에 대한 제한이 없는 경우에 박스를 제한할 때 사용한다.
대부분 상위 요소에서 정의된 제한에 따라 크기가 정해진다. 하지만 ListView, Column, Row와 같은 경우, 하위요소 크기에 제한을 두지 않는다.

이처럼 상위 요소의 제한이 존재하지 않을 때, 상위 요소 제한에 의존하는 위젯에는 어떻게 기본값을 줄 수 있을까?

이런 경우에 LimitedBox를 사용하면 된다!
LimitedBox를 사용하면 maxHeight와 maxWidth가 제공된다. 이는 child에게 무한한 상황에서 자연스러운 크기를 제공하는 효과가 있다.

경우를 나눠 정리해보면,

만약 위젯의 최대 너비가 제한되지 않았다면 이 위젯의 child의 너비는 maxWidth에 따라 제한된다.

같은 논리로, 만약 위젯의 최대 높이가 제한되지 않았다면 이 위젯의 child의 높이 또한 maxHeight에 제한된다.


Offstage class

offstage class는 말 그대로 stage에서 off(벗어난다)한다는 것으로 이해했다.

offstage class는 navigator와 비슷하게 페이지가 바뀌는 것처럼 보인다.
하지만, 새로운 페이지를 만들지 않아도 된다는 특징이자 장점이 있다.

또 다른 특징은 우리 눈에는 보이지 않지만 offstage 상태에서도 계속 실행되고 있기 때문에 우리 눈에 보이느냐 안보이느냐의 여부에 관계 없이 배터리가 소요된다.

이제 offstage에 대해 더 자세하게 이해하기 위해 예시 코드를 가져왔다.
전체 코드는 아래 링크로 두었으니 전체 코드가 궁금하다면 들어가길 바란다.



  1. offstage를 실행하기 전에 먼저 true로 값을 설정해준다.
bool _offstage = true;
  1. offstage가 true이면 물리적 공간이 눈에 보이지 않는다.
    반대로, offstage가 false이면 물리적 공간이 눈에 보인다.
@override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Offstage(
          offstage: _offstage,
          child: FlutterLogo(
            key: _key,
            size: 150.0,
          ),
        ),
        Text('Flutter logo is offstage: $_offstage'),
        ElevatedButton(
          child: const Text('Toggle Offstage Value'),
          onPressed: () {
            setState(() {
              _offstage = !_offstage;//false로 초기 설정한 값이 버튼을 누를 때마다 값이 바뀐다.
            });
          },
        ),
      ],
    );
  }

<초기화면>

<버튼 누른 후 화면>

전체 코드
https://dartpad.dev/?id=2bad6eb52a25efd3df702370db842253


OverflowBox class

이 위젯은 parent로부터 child에게 각각 다른 constraints를 부과하여 child가 parent를 overflow(넘치게. 즉 더 크게) 할 수 있게 한다.

overflowBox를 사용하지 않으면 parent에서 제시된 constraint를 벗어날 수 없다.
하지만 overflowBox를 사용하면 parent를 벗어난 constraint를 설정할 수 있고, 이렇게 설정한 constraint 안에서 parent를 벗어난 box를 만들 수 있다.


example)

out put)


SizedOverflowBox class

overflowBox와 비슷한 역할을 한다.
overflowBox와 다른 점은 constraint를 따로 설정하지 않고 이전에 설정된 parent의 constraint를 전달한다. SizedOverflowBox를 사용하면 parent로부터 전달된 constraint를 벗어난 box를 그릴 수 있다는 것이다.

example)

out put)


Transform class

transform class는 지금까지 본 위젯들 중 가장 재밌고 신기하게 다가왔다.

우리가 흔히 파워포인트나, 영상, 앱 사용 중 봤을 법한 기능들이 transform 위젯을 사용한 것이다.

아래 첨부한 영상을 보면 나도 모르게 '우와' 하게 될 것이다.

transform에는 정말 많은 기능들이 있는데, 그 중 3개의 기능을 소개하고자 한다.

1. Transform.rotate

  • child를 원하는 각으로 회전하는 것이다.

2. Transform.scale

  • child의 크기를 원하는 크기로 조정하는 것이다.

3. Transform.translate

  • child의 위치를 원하는 위치로 이동하는 것이다.

이 외에도 skew, 3D perspective 등 우리가 실제로 본 경험이 있는 것들도 transform 위젯을 통해 만들 수 있다.

참고영상) https://youtu.be/9z_YNlRlWfA

0개의 댓글