Flutter의 기본 TabBar 위젯은 인디케이터의 패딩을 전체 탭에 동일하게 적용할 수 있습니다. 하지만 특정 탭(예: 첫 번째 탭은 왼쪽만, 두 번째 탭은 오른쪽만 패딩 적용)에서 인디케이터의 모양을 다르게 표현하고 싶다면, 커스텀 데코레이션(Decoration) 을 만들어야 합니다.

이번 포스팅에서는 커스텀 인디케이터를 구현하는 방법을 코드와 함께 설명하겠습니다.
코드 개요
다음 코드는 두 개의 탭(예: '활동'과 '클리닉')에서 첫 번째 탭은 왼쪽에만, 두 번째 탭은 오른쪽에만 패딩을 적용하는 인디케이터를 그리는 예제입니다.
import 'package:flutter/material.dart';
class LeftRightIndicator extends Decoration {
const LeftRightIndicator();
@override
BoxPainter createBoxPainter([VoidCallback? onChanged]) {
return _LeftRightIndicatorPainter(this, onChanged);
}
}
class _LeftRightIndicatorPainter extends BoxPainter {
final LeftRightIndicator decoration;
_LeftRightIndicatorPainter(this.decoration, VoidCallback? onChanged)
: super(onChanged);
@override
void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) {
// 탭 하나의 영역(Rect)를 구함.
final rect = offset & configuration.size!;
// 인디케이터에 적용할 페인트 설정 (색상, 스타일)
final paint = Paint()
..color = Colors.blue
..style = PaintingStyle.fill;
// 인디케이터 높이(밑줄 두께)를 3으로 설정.
final double indicatorHeight = 3.0;
final double top = rect.bottom - indicatorHeight;
final double bottom = rect.bottom;
// 기본적으로 탭 전체 너비를 사용
double left = rect.left;
double right = rect.right;
// offset.dx 값을 활용하여 첫 번째 탭과 두 번째 탭을 구분
// offset.dx == 0 이면 첫 번째 탭(예: '활동')으로 간주 -> 왼쪽에만 패딩 적용
// 그 외의 경우(예: 두 번째 탭 '클리닉')는 오른쪽에만 패딩 적용
if (offset.dx == 0) {
left += 15;
} else {
right -= 15;
}
// 패딩이 적용된 영역으로 RRect 생성
final rRect = RRect.fromRectAndRadius(
Rect.fromLTRB(left, top, right, bottom),
const Radius.circular(0),
);
// 캔버스에 인디케이터를 그림
canvas.drawRRect(rRect, paint);
}
}
코드 상세 설명
1. LeftRightIndicator 클래스
클래스 역할:
Flutter의 Decoration 클래스를 상속받아 커스텀 인디케이터 데코레이션을 구현합니다.
createBoxPainter:
이 메서드를 통해 실제 그리기 작업을 담당하는 _LeftRightIndicatorPainter를 생성합니다.
Rect 계산:
offset & configuration.size!를 이용해 탭 하나의 영역을 계산합니다. 이 영역은 인디케이터가 그려질 기본 영역입니다.
Paint 설정:
blue 색상과 PaintingStyle.fill 스타일을 지정하여 인디케이터의 색상과 채움 방식을 설정합니다.
인디케이터 높이 및 위치:
indicatorHeight를 3.0으로 설정하고, 탭 영역의 하단에서 이 높이만큼 위쪽으로 인디케이터의 시작 위치(top)를 계산합니다.
패딩 로직:
기본적으로 left와 right는 탭의 전체 영역을 사용합니다.
첫 번째 탭: offset.dx 값이 0인 경우 왼쪽에 15px의 패딩을 추가합니다.
두 번째 탭: 그 외의 경우 오른쪽에 15px의 패딩을 적용합니다.
RRect 생성 및 그리기:
계산된 좌표를 기반으로 RRect 객체를 생성한 후, canvas.drawRRect 메서드로 인디케이터를 그립니다.
활용 방법
이 커스텀 인디케이터를 사용하기 위해서는 TabBar 위젯의 indicator 속성에 해당 데코레이션을 지정하면 됩니다. 예를 들어:
dart
복사
TabBar(
tabs: const [
Tab(text: '활동'),
Tab(text: '클리닉'),
],
indicator: const LeftRightIndicator(),
)
이렇게 하면 첫 번째 탭에서는 왼쪽에, 두 번째 탭에서는 오른쪽에만 패딩이 적용된 인디케이터가 표시됩니다.
참고로 이 방식은 탭의 순서가 두 개일 때 잘 작동합니다. 탭의 개수가 늘어나면 탭의 위치를 어떻게 구분할지에 대한 추가 로직이 필요합니다.
마무리
Flutter에서 기본 인디케이터 설정으로는 개별 탭마다 다른 패딩을 주기 어려운 경우, 커스텀 데코레이션을 활용하면 원하는 디자인을 쉽게 구현할 수 있습니다. 이번 포스팅의 코드를 기반으로 다양한 탭 인디케이터를 실험해 보며 자신만의 스타일을 만들어 보세요.
여러분의 Flutter 개발에 작은 도움이 되었기를 바랍니다!