개요
ConstrainedBox는 자식 위젯에 추가적인 제약 조건(constraints)을 적용하는 위젯입니다. 부모로부터 받은 제약 조건과 자체적으로 정의한 제약 조건을 결합하여 자식의 크기를 제어합니다.
참조: https://api.flutter.dev/flutter/widgets/ConstrainedBox-class.html
언제 사용하나요?
- 위젯의 최소 또는 최대 크기를 제한하고 싶을 때
- 자식 위젯이 특정 크기 범위 내에서만 크기를 가지도록 할 때
- 반응형 레이아웃에서 크기 제한이 필요할 때
- 스크롤 가능한 영역에서 최소 높이를 보장하고 싶을 때
- 이미지나 비디오의 최대 크기를 제한할 때
기본 사용법
// 최소 크기 설정
ConstrainedBox({
constraints: new Constraints({
minWidth: 100,
minHeight: 100
}),
child: Container({
color: 'blue'
})
})
// 최대 크기 설정
ConstrainedBox({
constraints: new Constraints({
maxWidth: 200,
maxHeight: 200
}),
child: Container({
color: 'red',
width: 300, // 200으로 제한됨
height: 300 // 200으로 제한됨
})
})
// 고정 크기 설정
ConstrainedBox({
constraints: Constraints.tight({ width: 150, height: 150 }),
child: Container({
color: 'green'
})
})
Props
constraints (필수)
값: Constraints
자식 위젯에 적용할 제약 조건입니다. Constraints는 다음과 같은 속성을 가집니다:
minWidth
: 최소 너비 (기본값: 0)maxWidth
: 최대 너비 (기본값: Infinity)minHeight
: 최소 높이 (기본값: 0)maxHeight
: 최대 높이 (기본값: Infinity)
// 다양한 제약 조건 예제
ConstrainedBox({
constraints: new Constraints({
minWidth: 100,
maxWidth: 300,
minHeight: 50,
maxHeight: 200
}),
child: child
})
child (선택)
값: Widget | undefined
제약 조건이 적용될 자식 위젯입니다.
Constraints 생성자
Constraints는 여러 편의 생성자를 제공합니다:
// 기본 생성자
new Constraints({
minWidth: 0,
maxWidth: Infinity,
minHeight: 0,
maxHeight: Infinity
})
// 타이트한 제약 (고정 크기)
Constraints.tight({ width: 100, height: 100 })
// 느슨한 제약 (최대 크기만 제한)
Constraints.loose({ width: 200, height: 200 })
// 확장 (부모 크기로 확장)
Constraints.expand() // 모든 방향으로 확장
Constraints.expand({ width: 300 }) // 너비는 300, 높이는 확장
Constraints.expand({ height: 400 }) // 높이는 400, 너비는 확장
제약 조건 결합
ConstrainedBox는 부모의 제약 조건과 자신의 제약 조건을 결합합니다:
// 부모 제약: min(50, 50), max(200, 200)
// ConstrainedBox 제약: min(100, 100), max(150, 150)
// 결과: min(100, 100), max(150, 150)
Container({
constraints: new Constraints({
minWidth: 50,
maxWidth: 200,
minHeight: 50,
maxHeight: 200
}),
child: ConstrainedBox({
constraints: new Constraints({
minWidth: 100,
maxWidth: 150,
minHeight: 100,
maxHeight: 150
}),
child: Container({ color: 'blue' })
})
})
실제 사용 예제
예제 1: 버튼 최소 크기 보장
const MinSizeButton = ({ onPressed, child, minWidth = 88, minHeight = 36 }) => {
return ConstrainedBox({
constraints: new Constraints({
minWidth: minWidth,
minHeight: minHeight
}),
child: ElevatedButton({
onPressed: onPressed,
child: child
})
});
};
// 사용
MinSizeButton({
onPressed: () => console.log('clicked'),
child: Text('OK') // 짧은 텍스트여도 최소 크기 보장
})
예제 2: 이미지 크기 제한
const ConstrainedImage = ({ src, maxSize = 300 }) => {
return Container({
decoration: BoxDecoration({
border: Border.all({ color: '#E0E0E0' }),
borderRadius: BorderRadius.circular(8)
}),
child: ConstrainedBox({
constraints: new Constraints({
maxWidth: maxSize,
maxHeight: maxSize
}),
child: Image({
src: src,
objectFit: 'contain'
})
})
});
};
예제 3: 반응형 카드
const ResponsiveCard = ({ title, content }) => {
return ConstrainedBox({
constraints: new Constraints({
minHeight: 100,
maxWidth: 400
}),
child: Card({
child: Padding({
padding: EdgeInsets.all(16),
child: Column({
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(title, {
style: TextStyle({
fontSize: 20,
fontWeight: 'bold'
})
}),
SizedBox({ height: 8 }),
Text(content, {
style: TextStyle({
fontSize: 16,
color: '#666'
})
})
]
})
})
})
});
};
예제 4: 스크롤 영역 최소 높이
const ScrollableContent = ({ children, minHeight = 300 }) => {
return SingleChildScrollView({
child: ConstrainedBox({
constraints: new Constraints({
minHeight: minHeight
}),
child: Column({
children: children
})
})
});
};
예제 5: 종횡비를 유지하는 제한된 박스
const ConstrainedAspectBox = ({
child,
aspectRatio = 16/9,
maxWidth = 600
}) => {
return ConstrainedBox({
constraints: new Constraints({
maxWidth: maxWidth
}),
child: AspectRatio({
aspectRatio: aspectRatio,
child: Container({
decoration: BoxDecoration({
color: '#F5F5F5',
borderRadius: BorderRadius.circular(12)
}),
child: child
})
})
});
};
// 사용 예: 비디오 플레이어
ConstrainedAspectBox({
aspectRatio: 16/9,
maxWidth: 800,
child: VideoPlayer({ url: 'video.mp4' })
})
중첩된 ConstrainedBox
여러 ConstrainedBox를 중첩할 때는 가장 제한적인 제약이 적용됩니다:
ConstrainedBox({
constraints: new Constraints({ minWidth: 200, minHeight: 200 }),
child: ConstrainedBox({
constraints: new Constraints({ minWidth: 100, minHeight: 100 }),
child: Container({ color: 'blue' })
})
})
// 결과: 최소 크기는 200x200
주의사항
- 부모의 제약 조건은 항상 우선시됩니다
- 충돌하는 제약 조건은 가장 제한적인 것이 적용됩니다
- 무한 크기 제약에서는 자식의 고유 크기가 사용됩니다
- 너무 많은 중첩은 레이아웃 성능에 영향을 줄 수 있습니다
- tight 제약은 자식의 크기를 완전히 무시합니다
관련 위젯
- Container: constraints 속성으로 동일한 기능 제공
- SizedBox: 고정 크기를 설정하는 간단한 방법
- LimitedBox: 무한 제약에서만 크기를 제한
- UnconstrainedBox: 자식의 제약을 제거
- OverflowBox: 부모의 제약을 벗어날 수 있게 허용