Container에서 테두리를 만드는 방법은 여러가지가 있습니다.
1. 전체 테두리 : Border.all()
2. 상하 / 좌우 테두리 : Border.symmetric(horizontal : ~~~, vertical : ~~~~~)
3. 지정 테두리 : Border()
Flutter에서 Container 위젯에 테두리(border)를 만드는 방법은 decoration 속성에 BoxDecoration을 설정함으로써 구현할 수 있습니다.
✅ Container 테두리 설정 방법
속성 | 설명 |
border: Border.all(...) | 전체 테두리 생성 |
border: Border(...) | 네 방향(Top, Right, Bottom, Left) 각각 설정 가능 |
borderRadius: BorderRadius.circular(...) | 둥근 테두리 설정 |
color vs Container.color | 테두리 색과 혼동하지 않도록 decoration.color 또는 Container.color 중 하나만 사용 |
BoxDecoration 필수 사용 여부 | border, borderRadius 사용 시 반드시 필요 |
📌 전체 예시 코드
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("Container Border 예시")),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// 전체 테두리
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(
color: Colors.blue,
width: 2,
),
),
child: Text('전체 테두리'),
),
SizedBox(height: 20),
// 네 방향 각각 다른 테두리
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border(
top: BorderSide(color: Colors.red, width: 2),
right: BorderSide(color: Colors.green, width: 2),
bottom: BorderSide(color: Colors.blue, width: 2),
left: BorderSide(color: Colors.orange, width: 2),
),
),
child: Text('방향별 테두리'),
),
SizedBox(height: 20),
// 둥근 테두리
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey[200],
border: Border.all(
color: Colors.purple,
width: 2,
),
borderRadius: BorderRadius.circular(12),
),
child: Text('둥근 테두리'),
),
],
),
),
),
));
}
+ Flutter Container에서 점선 테두리, 그림자 효과, 기타 테두리 스타일을 설정하는 방법
✅ 기타 테두리 스타일
스타일 | 구현 방법 | 설명 |
점선 테두리 | DottedBorder 패키지 사용 | 기본 Container는 점선을 직접 지원하지 않음 |
그림자 효과 | BoxShadow 사용 | BoxDecoration의 boxShadow 속성 사용 |
원형 테두리 | BoxDecoration + shape: BoxShape.circle | 원형 프로필 등 |
라운드 + 그림자 | borderRadius + boxShadow 조합 | 카드 UI 등에 활용 |
반투명 테두리 | Border.all(color: ...)에서 color.withOpacity() 사용 | 흐릿한 경계선 효과 |
내측 그림자 | CustomPainter 또는 BackdropFilter 활용 | 일반 boxShadow는 외부 그림자만 지원 |
패턴 테두리 | Canvas, CustomPaint 활용 | 테두리에 이미지/무늬 넣기 |
애니메이션 테두리 | AnimatedContainer 또는 TweenAnimationBuilder 사용 | 테두리 색상, 두께, 라운딩 변화 |
Gradient 테두리 | ShaderMask, Stack 활용 | 선형/원형 그라디언트 테두리 효과 |
※ 📦점선 테두리에서 필요한 패키지
# pubspec.yaml
dependencies:
dotted_border: ^2.0.0
📌 테두리 예제 코드
점선, (외측)그림자, 원형 테두리
import 'package:flutter/material.dart';
import 'package:dotted_border/dotted_border.dart'; // 점선 테두리 패키지
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text("고급 테두리 예시")),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// ✅ 1. 점선 테두리
DottedBorder(
color: Colors.blue,
strokeWidth: 2,
dashPattern: [6, 3], // 6px 그려지고 3px 비워짐
borderType: BorderType.RRect,
radius: Radius.circular(12),
child: Container(
height: 60,
alignment: Alignment.center,
child: Text('점선 테두리'),
),
),
SizedBox(height: 20),
// ✅ 2. 그림자 효과
Container(
height: 60,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
border: Border.all(color: Colors.grey),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
offset: Offset(4, 4),
blurRadius: 6,
),
],
),
child: Text('그림자 있는 테두리'),
),
SizedBox(height: 20),
// ✅ 3. 원형 테두리
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
shape: BoxShape.circle,
border: Border.all(color: Colors.pink, width: 3),
color: Colors.pink[50],
),
child: Center(child: Text("원형")),
),
SizedBox(height: 20),
// ✅ 4. 라운드 + 그림자
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
boxShadow: [
BoxShadow(
color: Colors.blueAccent.withOpacity(0.3),
offset: Offset(0, 4),
blurRadius: 8,
)
],
),
child: Text("라운드 + 그림자 효과"),
),
SizedBox(height: 20),
// ✅ 5. 반투명 테두리
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(
color: Colors.black.withOpacity(0.3),
width: 2,
),
),
child: Text("반투명 테두리"),
),
],
),
),
),
));
}
🔦 내측 그림자 (inner shadow)
class InnerShadowContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _InnerShadowPainter(),
child: Container(
width: 200,
height: 60,
alignment: Alignment.center,
child: Text('내측 그림자'),
),
);
}
}
class _InnerShadowPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final rect = Offset.zero & size;
final Paint paint = Paint()
..shader = RadialGradient(
center: Alignment.center,
radius: 0.8,
colors: [
Colors.black.withOpacity(0.2),
Colors.transparent,
],
stops: [0.9, 1.0],
).createShader(rect);
canvas.drawRect(rect, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
🎨 패턴 테두리
class PatternBorderContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return CustomPaint(
painter: _PatternBorderPainter(),
child: Container(
width: 200,
height: 80,
alignment: Alignment.center,
child: Text('패턴 테두리'),
),
);
}
}
class _PatternBorderPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = Colors.orange
..style = PaintingStyle.stroke
..strokeWidth = 3;
final path = Path();
// 사각형 외곽에 물결무늬 그리기
for (double i = 0; i < size.width; i += 10) {
path.moveTo(i, 0);
path.lineTo(i + 5, 5);
path.lineTo(i + 10, 0);
}
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false;
}
🌈 Gradient 테두리
class GradientBorderContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(3), // 테두리 두께
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.purple, Colors.blue]),
borderRadius: BorderRadius.circular(12),
),
child: Container(
height: 60,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
child: Text('그라디언트 테두리'),
),
);
}
}
🎞️ 애니메이션 테두리
class AnimatedBorderContainer extends StatefulWidget {
@override
_AnimatedBorderContainerState createState() => _AnimatedBorderContainerState();
}
class _AnimatedBorderContainerState extends State<AnimatedBorderContainer> {
bool _toggled = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => setState(() => _toggled = !_toggled),
child: AnimatedContainer(
duration: Duration(milliseconds: 500),
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
border: Border.all(
color: _toggled ? Colors.red : Colors.blue,
width: _toggled ? 4 : 2,
),
borderRadius: BorderRadius.circular(_toggled ? 24 : 4),
),
child: Text('애니메이션 테두리'),
),
);
}
}
TIP
● 점선 테두리에서 다른 모양(예: 원형, 사각형 등) 만들기
→ borderType을 BorderType.Circle, BorderType.RRect, BorderType.Rect 등으로 설정.
● boxShadow가 겹쳐서 부자연스러울 때
→ blurRadius, spreadRadius, offset 값을 조정하거나 그림자 색의 투명도를 낮추기.
● 테두리 애니메이션
→ AnimatedContainer를 사용하면 border, borderRadius, boxShadow 등도 애니메이션 처리 가능합니다.
● 그림자와 테두리는 Stack 또는 CustomPaint 조합으로 조절 가능.
● 패턴 테두리는 반복 그림(패턴 이미지)도 가능하니, ui.Image, ImageShader, TileMode 활용 가능.
● ClipRRect, BackdropFilter와 함께 쓰면 유리 효과 + 테두리도 가능.
● Container.color와 decoration.color를 동시에 쓰면 안 됨.
→ Container.color는 내부적으로 decoration 없이 단순 배경색을 설정하는 단축 속성이고, decoration이 명시되면 color는 무시되기 때문입니다.
'Flutter + Dart > Flutter + Dart TIP' 카테고리의 다른 글
TextStyle 속성 정리 (0) | 2025.05.13 |
---|---|
Flutter 위젯 카탈로그 (0) | 2025.05.13 |
기타 (0) | 2025.05.13 |
jdk 환경설정 경로가 맞는데도 올류 날 때 (0) | 2025.05.09 |
Flutter Icon 모음 (0) | 2025.05.09 |