[Flutter] BackdropFilter로 Blur 효과 주기

CHOI·2022년 1월 30일
5

[Flutter] 위젯

목록 보기
3/6
post-thumbnail

Blur 효과

토스 앱의 상품권 구매 페이지를 보면 페이지 스크롤 시 appbar가 blur 효과를 볼 수 있다.
Flutter에서 blur 효과를 주는 방법을 알아보자.


BackdropFilter

Flutter에서 blur 효과를 주기 위해서는 BackdropFilter 위젯을 이용하는 방법이 있다.

BackdropFilter
기존 페인팅 된 콘텐츠에 필터를 적용한 다음 자식을 페인팅하는 위젯입니다.
필터는 상위 또는 상위 위젯의 클립 내의 모든 영역에 적용됩니다. 클립이 없으면 필터가 전체 화면에 적용됩니다.

출처: https://api.flutter.dev/flutter/widgets/BackdropFilter-class.html

Stack

우선 리스트 위의 appbar에 blur 효과를 주기 위해서는 Stack으로 구현을 해야 된다.
리스트를 스크롤 해도 appbar는 항상 리스트보다 상단에 있어야 되기 때문에 appbar를 Stack에서 제일 아래쪽에 위해줬다.

Stack(
  children: [
    // 리스트.
    _list(),

    // 앱바.
    _appbar(),
  ],
)

// 앱바.
Widget _appbar() {
  return Container(
    height: _appBarHeight,
    width: double.infinity,
    alignment: Alignment.bottomLeft,
    color: _appBarColors,
    padding: const EdgeInsets.all(16),
    child: const Icon(
      Icons.arrow_back_ios_outlined,
    ),
  );
}

addListener

스크롤이 제일 상단에 있을 때는 appbar의 색상이 없다.
하지만 스크롤을 할 때는 투명도가 있는 회색 색상으로 바뀌기 때문에 리스트 컨트롤러에 addListener를 추가해서 스크롤 할 때 색상을 변경해 주었다.

// scroll controller.
late ScrollController _scrollController;

// change app bar color
void _changeAppBarColor() {
  if (_scrollController.hasClients) {
    if (_scrollController.offset > 0) {
      _appBarColors = Colors.grey.shade800.withOpacity(0.5);
    } else {
      _appBarColors = Colors.transparent;
    }

    // 상태 변경.
    setState(() {});
  }
}


void initState() {
  super.initState();
  _scrollController = ScrollController()..addListener(_changeAppBarColor);
}

BackdropFilter

기본 준비는 끝났다.
이제 appbar에 BackdropFilter 위젯으로 감싸주면 끝난다.
BackdropFilter의 filter 값으로 blur 효과의 값을 정할 수 있다.

simaX은 x축 값이다. 즉, 가로로 효과를 얼마를 부여할지 정할 수 있다. 반대로 simaY는 Y축으로 세로로 효과를 얼마를 부여할지 정할 수 있다.

BackdropFilter(
  filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
  child: appbar...
);

✅ sigmaX와 sigmaY에 값을 넣었는데도 blur 효과가 없다면 BackdropFilter의 child의 색상을 확인해 보자. 색상의 투명도가 부여되야지만 blur 효과를 정확하게 표현이 가능하다.

.withOpacity(double opacity)

‼️ appbar 위젯에만 BackdropFilter를 부모 위젯으로 감싸주었는데 blur 효과가 전체 화면에 효과가 들어갔다.

공식 문서를 다시 보니 해결 방법이 나와있다.

The filter will be applied to all the area within its parent or ancestor widget's clip. If there's no clip, the filter will be applied to the full screen.

필터는 상위 또는 상위 위젯의 클립 내의 모든 영역에 적용됩니다. 클립이 없으면 필터가 전체 화면에 적용됩니다.

ClipRRect(
  child: BackdropFilter(
    filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
    child: appbar...
  ),
);

profile
Mobile App Developer

1개의 댓글

comment-user-thumbnail
2022년 7월 5일

감사합니다 덕분에 해결했어요~ ClipRRect ! 공식문서의 중요성을 다시느낍니다ㅏ

답글 달기