[Flutter] 탭 인디케이터 만들기

길위에 히피·2025년 2월 21일

Flutter

목록 보기
45/56

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를 생성합니다.

  1. _LeftRightIndicatorPainter 클래스
    paint 메서드:
    인디케이터를 그리는 핵심 메서드입니다.

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 개발에 작은 도움이 되었기를 바랍니다!

profile
마음맘은 히피인 일꾼러

0개의 댓글