본문 바로가기
Flutter + Dart/Flutter + Dart TIP

Container에서 테두리를 만드는 방법

by GREEN나무 2025. 5. 13.
728x90

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