본문 바로가기

카테고리 없음

[ j Flutter ] Flutter withOpacity() deprecated? 왜 바뀌었고 뭘 써야 할까?

728x90
반응형

Flutter withOpacity() deprecated? 왜 바뀌었고 뭘 써야 할까

Flutter로 UI를 만들다 보면 색상을 투명하게 만들 때 습관처럼 withOpacity()를 자주 쓴다.

 
Colors.black.withOpacity(0.3)

그런데 어느 순간부터 IDE에서 경고가 뜨거나(혹은 팀 코드리뷰에서) “withOpacity deprecated 됐으니 바꾸자” 같은 이야기가 나온다.
정리해보면 핵심은 이거다:

  • withOpacity() 자체가 “색상을 투명하게 만드는 기능”은 맞다.
  • 하지만 정확도/일관성(특히 8-bit 알파 변환) 측면에서 더 권장되는 방식이 생겼고,
  • Flutter는 그 방향으로 코딩 스타일을 유도하고 있다.

이번 글에서는 withOpacity()가 왜 문제로 언급되는지, 그리고 실무에서 무엇으로 바꾸는 게 좋은지 정리한다.


1) withOpacity()가 왜 문제로 보일까?

withOpacity(double opacity)는 0.0 ~ 1.0 사이의 double 값을 받아서 색상의 알파(투명도)를 바꿔준다.

문제는 알파값이 최종적으로는 0~255의 8-bit 정수(ARGB) 로 저장된다는 점이다.
즉, 0.3 같은 double은 결국 255에 곱해져서 정수로 변환된다.

  • 0.3 × 255 = 76.5 → 반올림/버림 규칙에 따라 76 또는 77
  • 플랫폼/렌더링 경로/컴파일 최적화 등의 조건에 따라 “미세한 차이”가 누적될 수 있다

이건 “앱이 망가진다” 급 문제는 아니지만,

  • 픽셀 퍼펙트한 UI
  • 디자인 시스템에서 동일 색상을 강제
  • 테스트/스냅샷 비교
    같은 환경에선 이런 알파 변환 방식이 싫어질 수 있다.

그래서 Flutter 쪽에서 권장되는 방향이:

애초에 알파를 정수(0~255)로 확정해서 쓰자
→ withAlpha(int a) 또는 Color.fromARGB(...)


2) 대안 1: withAlpha() (가장 간단하고 실무적)

 
Colors.black.withAlpha(77) // 약 30% (0.3*255 ≈ 76.5)

장점

  • 알파가 정수로 고정됨 (예측 가능)
  • 테마/디자인 시스템에 “정확한 색”으로 박아넣기 좋음

단점

  • “0.3 같은 감각적인 값”이 아니라 77처럼 계산이 필요함

팁:
opacity → alpha 변환은 alpha = (opacity * 255).round() 로 많이 쓴다.

예)

  • 10% → 26
  • 20% → 51
  • 30% → 77
  • 40% → 102
  • 50% → 128
  • 60% → 153
  • 70% → 179
  • 80% → 204
  • 90% → 230

3) 대안 2: Color.fromARGB() / Color.fromRGBO()

디자인에서 “RGB + 투명도”가 딱 떨어져 나온다면 이 방식이 더 명확하다.

 
const c = Color.fromARGB(77, 0, 0, 0); // 검정 30%

또는 RGBO:

 
const c = Color.fromRGBO(0, 0, 0, 0.3);

실무 추천은 보통:

  • 디자인 시스템 상수화: fromARGB
  • 빠른 UI 조정: withAlpha
  • 프로토타이핑/임시: fromRGBO

4) “그럼 withOpacity()는 완전 금지인가?”

아니. 대부분의 앱에서 withOpacity()는 여전히 잘 동작하고 큰 문제도 없다.
다만 팀/프로젝트가 커질수록 “색상 정의가 흔들리지 않게” 관리하는 게 중요해지고, 그 과정에서 더 예측 가능한 방식이 선호된다.

정리하면:

  • 개인 프로젝트/간단 UI: withOpacity() 써도 큰 문제 없음
  • 디자인 시스템/테마/대규모 코드베이스: withAlpha()/fromARGB() 권장

5) 마이그레이션 예시 (실제로 이렇게 바꾸면 됨)

Before

 
final overlay = Colors.black.withOpacity(0.3);
final border = theme.colorScheme.primary.withOpacity(0.12);

After (권장)

 
final overlay = Colors.black.withAlpha(77); 
final border = theme.colorScheme.primary.withAlpha(31); 
 
class AppColors { static const overlay30 = Color.fromARGB(77, 0, 0, 0); }

6) 실무 팁: opacity를 쓰고 싶다면 “알파 테이블”을 만들어라

프로젝트에서 자주 쓰는 opacity가 반복된다면,
아예 표준 알파를 정해서 관리하는 게 편하다.

예:

  • overlay: 30% (77)
  • divider: 12% (31)
  • disabled: 38% (97)

이런 식으로 팀이 합의한 값으로 통일하면
“어느 화면은 0.29, 어느 화면은 0.3” 같은 미세한 흔들림이 사라진다.


마무리

withOpacity()는 편하지만,
결국 8-bit 알파로 변환되는 과정에서 정확도/일관성 이슈가 생길 수 있고,
그래서 Flutter 코드 스타일은 점점 withAlpha() 또는 ARGB 기반으로 이동하는 흐름이다.

개인 앱이라면 withOpacity()가 크게 문제되지 않지만,
디자인 시스템이 있는 앱이라면 이참에 색상 정의를 정수 알파 기준으로 정리해두는 걸 추천한다.


728x90
반응형