Flutter - #16. Positioned

Pearl Lee·2021년 6월 12일
1

Flutter Widget

목록 보기
16/50

내가 보려고 쓰는 Flutter 일기
출처1 : https://api.flutter.dev/flutter/widgets/Stack-class.html
출처2 : https://api.flutter.dev/flutter/widgets/Positioned-class.html
출처3 : https://api.flutter.dev/flutter/dart-ui/Clip-class.html





Positioned

지난 일기에서 다뤄본 Stack에 이어, 오늘은 Positioned 를 배워보자.
Stack의 자식 위젯 위치를 조절하는데 쓰인다. Positioned 위젯은 Stack 안에서 사용되어야 하며, StatelessWidget과 StatefulWidget에서만 사용가능하다고 한다. RenderObjectWidget 같은 다른 종류의 위젯은 안된다고 한다. 근데 그게 뭐지..?

지난 시간에 돌려본 코드를 가져와서 변형시켜보자.








코드 예시로 알아보자

우선 지난번 Stack일기에서 돌려본 코드는 다음과 같다.

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

/// This is the main application widget.
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  static const String _title = 'Test Stack';

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: _title,
      home: Scaffold(
        appBar: AppBar(title: const Text(_title)),
        body: const Center(
          child: StackWidget(),
        ),
      ),
    );
  }
}


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

  
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          width: 200,
          height: 200,
          color: Colors.red,
        ),
        Container(
          width: 150,
          height: 150,
          color: Colors.green,
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.blue,
        ),
      ],
    );
  }
}

Stack class의 속성들 중 alignment는 topStart로, fit은 loose로 이미 초기화가 되어있다는 사실을 기억하자.

Stack에서 맨 위에 위치하게 되는 마지막 자식 위젯을 Positioned 로 감싸보았다.

Positioned(
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),
초기 상태left : 50left : 50, top : 30
초기 상태left : 50left : 50, top : 30

위와 같이 간단히 위치를 조절할 수 있다.






Positioned 는 어떻게 생겼나


const Positioned({
    Key? key,
    this.left,
    this.top,
    this.right,
    this.bottom,
    this.width,
    this.height,
    required Widget child,
  }) : assert(left == null || right == null || width == null),
       assert(top == null || bottom == null || height == null),
       super(key: key, child: child);

간단하게 생겼다. 요기서 위치나 크기를 조절하고, 튀어나가는 부분은 Stack의 속성을 조절해서 같이 쓰면 삐져나갈 부분도 화면에 나타낼 수 있다. 나중에 코드를 돌려보자.



width, height 지정해주면 크기도 조절가능!

Positioned(
          width: 50,
          height: 50,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),

그런데 만약 이렇게 작성하면, Container 안의 width, height 는 무시하고 Positioned의 width, height값에 따라 화면에 나타나게 된다.










이번엔 두번째 자식 요소에 손을 대보자

이전 예시에서 세번째 자식 요소를 Positioned로 감싸주었는데, 이번에는 두번째 자식 요소 위젯을 Positioned 로 감싸보자. Positioned 의 top, bottom, left, right는 마이너스 값을 줄 수도 있다.

 
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Container(
          width: 200,
          height: 200,
          color: Colors.red,
        ),
        Positioned(
          bottom: 0,
          right: 0,
          child: Container(
            width: 150,
            height: 150,
            color: Colors.green,
          ),
        ),
        Container(
          width: 100,
          height: 100,
          color: Colors.blue,
        ),
      ],
    );
  }
bottom : 0, right: 0bottom : 20, right : 20
bottom : 0, right: 0bottom : 20, right : 20







그런데 마이너스 값을 주면 원래 너비와 높이만큼 나타나지는 못하고, 위와 같이 -20만큼 잘려서 화면에 나온다.
잘리지 않고 그대로 나오게 할 방법은 없을까?

Stack의 clipBehavior 속성을 none으로 설정하면 된다.
clipBehavior의 기본값은 Clip.hardEdge 이다. 출처3에 표시해둔 링크에 들어가보면 Clip에 관한 설명이 있다. 난 다 읽어보진 않았다.

clipBehavior: Clip.noneclipBehavior: Clip.hardEdge
Clip.noneClip.hardEdge








위젯을 여러 개 쌓을 때, 세세한 위치 조정이 필요하다면 Positioned를 사용할 수 있을 것이다.


오늘의 일기는 여기까지!

profile
안 되면 되게 하라

0개의 댓글