[플러터] 12. 위젯의 Constraints

KangHo Lee's avatar
Dec 27, 2024
[플러터] 12. 위젯의 Constraints

1. 자식 위젯은 부모 위젯의 Contraints에 영향을 받는다.

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: Text('Constraints Example')), body: Center( child: Container( color: Colors.blue, constraints: BoxConstraints( // constraints -> 제약 조건 걸기 minWidth: 100, minHeight: 100, maxWidth: 200, maxHeight: 200, ), child: Container( color: Colors.red, width: 30, height: 30, child: Center(child: Text('Child')), ), ), ), ), ); } }
notion image
  • 자식 위젯의 높낮이를 30, 30으로 했지만 부모의 제약 조건(min) 때문에 100, 100이 된 모습입니다.
  • 자식 위젯의 높낮이가 max를 넘으면 마찬가지로 max값인 200까지만 커집니다.
  • 자식 위젯의 높낮이를 설정하지 않을 경우 부모 제약 조건인 maxWidth, maxHeight인 200이 적용됩니다.

2. 부모 위젯의 제약 조건을 피하는 방법 1 - 중간 위젯 삽입

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Container( width: 100, height: 100, decoration: BoxDecoration( border: Border.all(), borderRadius: BorderRadius.circular(50), // 50이 정원(100의 반) ), child: Align( // 부모 컨테이너 특징을 물려받지 않기 위해 중간에 배치 위젯을 넣음 child: Container( width: 80, height: 80, decoration: BoxDecoration( borderRadius: BorderRadius.circular(40), color: Colors.red, ), ), ), ) ], ), ); } }
notion image
  • Align위젯으로 자식 Container를 감싸서 자식 컨테이너의 크기가 부모 컨테이너의 제약 조건에 걸리지 않도록 했습니다.
  • BorderRadius.circular(50)
    • 원의 크기가 100일 때 이 값을 반(50)만큼 주면 정원이 됩니다.

3. 부모 위젯의 제약 조건을 피하는 방법 2 - Stack 위젯 활용

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Stack( children: [ // stack은 먼저 넣은 위젯이 아래로 간다. Container( width: 100, height: 100, decoration: BoxDecoration( border: Border.all(), borderRadius: BorderRadius.circular(50), ), ), Positioned( left: 10, top: 10, child: Container( width: 80, height: 80, decoration: BoxDecoration( border: Border.all(), borderRadius: BorderRadius.circular(40), ), ), ), ], ), ], ), ); } }
notion image
  • Stack 위젯에 부모와 자식 위젯을 집어 넣고 자식 위젯을 Positioned 위젯으로 감싸는 방법으로도 부모의 제약 조건을 피할 수 있습니다.

4. Stack을 활용해서 두 위젯을 겹치게 배치

import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: HomePage(), ); } } class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Column( children: [ Stack( children: [ Container( height: 200, width: 100, ), Container( width: 100, height: 100, decoration: BoxDecoration( border: Border.all(), borderRadius: BorderRadius.circular(50) ), ), Positioned( left: 10, top: 50, child: Container( width: 80, height: 80, decoration: BoxDecoration( border: Border.all(), borderRadius: BorderRadius.circular(40) ), ), ), ], ), Divider(), Stack( children: [ TextFormField( decoration: InputDecoration( hintText: "Username", contentPadding: EdgeInsets.only(top: 100, left: 20), suffixIcon: Icon(Icons.do_not_disturb_on_total_silence), focusedBorder: OutlineInputBorder(), enabledBorder: OutlineInputBorder(), ), ), Positioned( left: 15, top: 20, child: Icon(Icons.person), ), ], ) ], ), ); } }
notion image
notion image
  • stack 위젯의 크기는 제일 아래 위젯 크기가 되기 때문에 왼쪽 위의 모양처럼 원이 제대로 나오지 않을 경우 제일 아래 위젯의 크기를 늘리면 됩니다.
  • 오른쪽 위의 그림에서 TextFormField에 사람 모양 아이콘을 Positioned로 겹치지 않게 배치했습니다.
 
Share article

devleekangho