Flutter withOpacity() deprecated? 왜 바뀌었고 뭘 써야 할까
Flutter로 UI를 만들다 보면 색상을 투명하게 만들 때 습관처럼 withOpacity()를 자주 쓴다.
그런데 어느 순간부터 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() (가장 간단하고 실무적)
장점
- 알파가 정수로 고정됨 (예측 가능)
- 테마/디자인 시스템에 “정확한 색”으로 박아넣기 좋음
단점
- “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 + 투명도”가 딱 떨어져 나온다면 이 방식이 더 명확하다.
또는 RGBO:
실무 추천은 보통:
- 디자인 시스템 상수화: fromARGB
- 빠른 UI 조정: withAlpha
- 프로토타이핑/임시: fromRGBO
4) “그럼 withOpacity()는 완전 금지인가?”
아니. 대부분의 앱에서 withOpacity()는 여전히 잘 동작하고 큰 문제도 없다.
다만 팀/프로젝트가 커질수록 “색상 정의가 흔들리지 않게” 관리하는 게 중요해지고, 그 과정에서 더 예측 가능한 방식이 선호된다.
정리하면:
- 개인 프로젝트/간단 UI: withOpacity() 써도 큰 문제 없음
- 디자인 시스템/테마/대규모 코드베이스: withAlpha()/fromARGB() 권장
5) 마이그레이션 예시 (실제로 이렇게 바꾸면 됨)
Before
final border = theme.colorScheme.primary.withOpacity(0.12);
After (권장)
final border = theme.colorScheme.primary.withAlpha(31);
6) 실무 팁: opacity를 쓰고 싶다면 “알파 테이블”을 만들어라
프로젝트에서 자주 쓰는 opacity가 반복된다면,
아예 표준 알파를 정해서 관리하는 게 편하다.
예:
- overlay: 30% (77)
- divider: 12% (31)
- disabled: 38% (97)
이런 식으로 팀이 합의한 값으로 통일하면
“어느 화면은 0.29, 어느 화면은 0.3” 같은 미세한 흔들림이 사라진다.
마무리
withOpacity()는 편하지만,
결국 8-bit 알파로 변환되는 과정에서 정확도/일관성 이슈가 생길 수 있고,
그래서 Flutter 코드 스타일은 점점 withAlpha() 또는 ARGB 기반으로 이동하는 흐름이다.
개인 앱이라면 withOpacity()가 크게 문제되지 않지만,
디자인 시스템이 있는 앱이라면 이참에 색상 정의를 정수 알파 기준으로 정리해두는 걸 추천한다.