티스토리 뷰

플러터 (Flutter)

[Flutter] Ticker에 대하여

Dev Ttangkong 2023. 6. 12. 16:32

 

플러터에서 애니메이션을 구현하는 기반 클래스는 Ticker입니다. Ticker는 프레임이 업데이트될 때마다 등록한 콜백 함수를 호출하고 프레임이 업데이트되기까지 경과한 시간을 정의해주는 역할을 하는 녀석입니다.

 

하지만 우리는 대부분 티커의 인스턴스를 직접 생성하지는 않습니다.

(물론 인스턴스를 생성하여 사용할 수도 있습니다.)

 

TickerProvider라는 공급자 역할을 하는 클래스에 의해 Ticker를 생성합니다. (아마 Ticker와 관련된 위젯이나 기능들이 dispose되면 자동으로 함께 dispose될 수 있도록하기 위한 관리 용이성 때문인듯 합니다)

 

위젯 상태 내에서 애니메이션을 구현한다면 주로 SingleTickerProviderStateMixin 또는 TickerProviderStateMixin 믹스인을 사용하여 해당 클래스가 TickerProvider으로 동작 될 수 있도록 선언합니다.

 

// 해당 선언부에서 TickerProviderStateMixin이(가) TickerProvider으로 인터페이스를 구현하는 것을 알 수 있습니다.
// 이로서 해당 인터페이스를 선언한 클래스는 TickerProvider 으로서도 정의될 수 있다는 것을 알 수 있습니다.
mixin SingleTickerProviderStateMixin<T extends StatefulWidget> on State<T> implements TickerProvider { ... }

// 보통 해당 방식으로 사용됩니다.
class WidgetState extends State<...> with SingleTickerProviderStateMixin {

	/// 여기서 [vsync]는 TickerProvider를 의미합니다.
	late final animation = AnimationController(vsync: this);
}

 

하지만 기본적으로 제공되는 플러터의 TickerProvider를 가지고 충분히 다양한 애니메이션을 만들 수 있지만 스크롤 물리 같은 동적으로 속도가 변화하고 프레임이 달라도 일정한 속도로 이동하는 애니메이션을 구현해야 한다면 아래와 같은 로직을 선언하여 Delta 형태으로 구현해야 할 수도 있습니다.

(0.1초 간격으로 업데이트하면 되겠지? 라고 생각하시는 분들이 있다면 빨리 주변 벽에 머리를 박으시길 바랍니다.)

 

/// 주어지는 [deltaElapsed]는 이전 프레임의 시간과 현재 프레임의 시간 차이를 정의합니다.
@protected
typedef DeltaTickerCallBack = void Function(Duration deltaElapsed);

@protected
class DetlaTickerProvider<T extends TickerProvider> {
  DetlaTickerProvider({
    required this.vsync,
  });

  final T vsync;

  Ticker createTicker(DeltaTickerCallBack callBack) {
    Duration previousElapsed = Duration.zero;

    return vsync.createTicker((elapsed) {
      Duration delta = elapsed - previousElapsed;
      previousElapsed = elapsed;

      callBack.call(delta);
    });
  }
}