Study Record

[Flutter] 위젯 겹치기 (Stack, Positioned) , 배경 불투명 본문

Flutter/widget

[Flutter] 위젯 겹치기 (Stack, Positioned) , 배경 불투명

초코초코초코 2023. 2. 18. 15:44
728x90

✍ Stack Class

자식 위젯들을 중복으로 겹쳐서 위치시킬 수 있다. 별도로 방향을 정해주지 않으면 상단 왼쪽(topStart)에 위젯들이 겹쳐 정렬된다.

Stack({   
  Key? key,   
  AlignmentGeometry alignment = AlignmentDirectional.topStart,
  TextDirection? textDirection,  
  StackFit fit = StackFit.loose, 
  Clip clipBehavior = Clip.hardEdge,
  List  children = const  [], 
})

 

※ alignment

 

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(home: HomeScreen()));
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      body: Column(
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              contentWidget(AlignmentDirectional.topStart, "topStart"),
              contentWidget(AlignmentDirectional.topCenter, "topCenter"),
              contentWidget(AlignmentDirectional.topEnd, "topEnd"),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              contentWidget(AlignmentDirectional.centerStart, "centerStart"),
              contentWidget(AlignmentDirectional.center, "center"),
              contentWidget(AlignmentDirectional.centerEnd, "centerEnd"),
            ],
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              contentWidget(AlignmentDirectional.bottomStart, "bottomStart"),
              contentWidget(AlignmentDirectional.bottomCenter, "bCenter"),
              contentWidget(AlignmentDirectional.bottomEnd, "bottomEnd"),
            ],
          ),
        ],
      ),
    );
  }

  Widget contentWidget(AlignmentGeometry alignment, String alignmentStr) {
    return Stack(
      alignment: alignment,
      children: <Widget>[
        Container(
          width: 100,
          height: 100,
          color: Colors.red,
        ),
        Container(
          width: 90,
          height: 90,
          color: Colors.green,
        ),
        Container(
          width: 80,
          height: 80,
          color: Colors.blue,
        ),
        Text(alignmentStr, style: TextStyle(fontWeight: FontWeight.bold)),
      ],
    );
  }
}

 

 

✍ Stack + Positioned

Stack의 alignment 인자로 하위 위젯들을 정렬시킬 수 있지만 Positioned 를 사용하면 하위 위젯 각각의 위치를 정할 수 있다.

Positioned({  
  Key? key,  
  double? left,   
  double? top,   
  double? right,  
  double? bottom,  
  double? width,  
  double? height,   
  required Widget child,
})

각각 위치(left, top 등)마다 width, height 를 정해준 단위와 똑같이 값을 정해주면 된다. 만약 top 이 30.0 이라면 위에서부터 30.0 만큼 떨어진 위치라는 의미가 된다.

 

예시)

Container(
  color: Colors.orange,
  width: 300.0,
  height: 500.0,
    child: Stack(
      fit: StackFit.loose,
      alignment: AlignmentDirectional.topStart,
      children: <Widget>[
        Positioned(
          bottom: 200,
          left: 100,
          child: Container(
            width: 100,
            height: 100,
            color: Colors.red,
            child: Center(child: Text("bottom : 200, left : 100")),
          ),
        ),
        Positioned(
          left: 0,
          right: 0,
          child: Container(
            width: 50,
            height: 50,
            color: Colors.green,
            child: Center(child: Text("right : 0, left : 0")),
          ),
        ),
        Positioned(
          bottom: 0,
          child: Container(
            width: 100,
            height: 50,
            color: Colors.lightBlue,
            child: Center(child: Text("bottom : 0")),
          ),
        ),
      ],
    ),
  )

초록색 박스는 right 가 0 left 가 0 이다. 이러면 right 에서 0만큼 left 에서 0 만큼 떨어지도록 설정했기 때문에 하위 위젯의 width 가 50 이어도 좌우로 늘어났다. 기본 Stack의 alignment 가 topStart 이기 때문에 상단에 배치하게 된다.

빨간 박스는 딱 중앙에 오도록 배치했는데 하위 위젯의 중심에서 떨어진 거리가 아니라 위젯의 끝부터 길이를 재기 때문에 너비 300 크기에서 왼쪽에서 100만큼(left: 100) 주면 하위 위젯크기가 100 이기 때문에 딱 150 에 하위 위젯의 중심에 위치된다. 높이도 전체 500 에서 아래에서 200만큼(bottom: 200) 주면 하위 위젯크기가 100이기 때문에 250 에 하위 위젯의 중심에 위치된다.

파랑 박스는 bottom에서 0만큼만 떨어졌으니 하단에 딱 붙어있고 Stack의 alignment가 topStart 이기 때문에 왼쪽에 배치하게 된다.

 

 

 

 

Stack class - widgets library - Dart API

A widget that positions its children relative to the edges of its box. This class is useful if you want to overlap several children in a simple way, for example having some text and an image, overlaid with a gradient and a button attached to the bottom. Ea

api.flutter.dev

 

 

Positioned class - widgets library - Dart API

A widget that controls where a child of a Stack is positioned. A Positioned widget must be a descendant of a Stack, and the path from the Positioned widget to its enclosing Stack must contain only StatelessWidgets or StatefulWidgets (not other kinds of wid

api.flutter.dev

 

 

+ Stack 을 이용한 배경 불투명하게 만들기

Stack(
  alignment: AlignmentDirectional.center,
  children: [
    Container(
      width: 300.0,
      height: 200.0,
      decoration: BoxDecoration(
        gradient: LinearGradient(
          begin: Alignment.topCenter,
          end: Alignment.bottomCenter,
          colors: <Color>[
            Colors.black.withAlpha(0),
            Colors.black12,
            Colors.black45
          ],
        ),
      ),
    ),
    const Positioned(
      bottom: 20.0,
      child: Text(
        "불투명 배경 테스트",
        style: TextStyle(color: Colors.black),
      ),
    )
  ],
)

 

728x90