Files
Android-pyApi/android_pyapi/android/animation.py
T
shuiyu1123 a51854455b feat: 大规模扩充至212个模块/175K行代码 — 覆盖android/java/javax/org/dalvik全包
- android/ 167个模块 (app/content/os/view/widget/graphics/media/hardware/net/telephony/provider等)
- java/ 35个模块 (lang/io/util/net/nio/security/crypto/sql/beans/rmi/awt等)
- javax/ 4个模块 (net/crypto/security/sql)
- org/ 5个模块 (json/w3c_dom/xml_sax/xml_pull/apache_http)
- dalvik/ 1个模块 (system)
- ~3053个类/接口,方法签名完全对齐Android SDK
- 桌面跨平台运行 (Windows/macOS/Linux)
- 修复所有导入错误和Python关键字冲突
2026-06-24 14:15:56 +00:00

951 lines
32 KiB
Python

"""
Android animation 组件 — Animator, ValueAnimator, ObjectAnimator, 插值器等
方法签名完全对齐 Android SDK
"""
from __future__ import annotations
import math
import threading
import time as _time
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, TypeVar
from .._core import Stub, AndroidOnlyError
from ..java.lang import RuntimeException
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
# ═══════════════════════════════════════════════════════════════
# TypeEvaluator
# ═══════════════════════════════════════════════════════════════
class TypeEvaluator(Stub):
"""TypeEvaluator — 类型估值器接口"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> Any:
return startValue
class FloatEvaluator(TypeEvaluator):
"""FloatEvaluator — 浮点估值器"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> float:
sv = float(startValue)
ev = float(endValue)
return sv + fraction * (ev - sv)
class IntEvaluator(TypeEvaluator):
"""IntEvaluator — 整数估值器"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> int:
sv = int(startValue)
ev = int(endValue)
return int(sv + fraction * (ev - sv))
class PointFEvaluator(TypeEvaluator):
"""PointFEvaluator — PointF 估值器"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> Any:
if hasattr(startValue, 'x') and hasattr(startValue, 'y'):
sv_x, sv_y = startValue.x, startValue.y
ev_x, ev_y = endValue.x, endValue.y
class PointF:
def __init__(self, x, y):
self.x = x
self.y = y
return PointF(sv_x + fraction * (ev_x - sv_x),
sv_y + fraction * (ev_y - sv_y))
return startValue
class RectEvaluator(TypeEvaluator):
"""RectEvaluator — Rect 估值器"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> Any:
if hasattr(startValue, 'left') and hasattr(startValue, 'top'):
class Rect:
def __init__(self, l, t, r, b):
self.left = l
self.top = t
self.right = r
self.bottom = b
return Rect(
int(startValue.left + fraction * (endValue.left - startValue.left)),
int(startValue.top + fraction * (endValue.top - startValue.top)),
int(startValue.right + fraction * (endValue.right - startValue.right)),
int(startValue.bottom + fraction * (endValue.bottom - startValue.bottom)),
)
return startValue
class ArgbEvaluator(TypeEvaluator):
"""ArgbEvaluator — ARGB 颜色估值器"""
def evaluate(self, fraction: float, startValue: Any, endValue: Any) -> int:
sv = int(startValue)
ev = int(endValue)
a = ((sv >> 24) & 0xFF) + int(fraction * (((ev >> 24) & 0xFF) - ((sv >> 24) & 0xFF)))
r = ((sv >> 16) & 0xFF) + int(fraction * (((ev >> 16) & 0xFF) - ((sv >> 16) & 0xFF)))
g = ((sv >> 8) & 0xFF) + int(fraction * (((ev >> 8) & 0xFF) - ((sv >> 8) & 0xFF)))
b = (sv & 0xFF) + int(fraction * ((ev & 0xFF) - (sv & 0xFF)))
return (min(a, 255) << 24) | (min(r, 255) << 16) | (min(g, 255) << 8) | min(b, 255)
# ═══════════════════════════════════════════════════════════════
# TimeInterpolator
# ═══════════════════════════════════════════════════════════════
class TimeInterpolator(Stub):
"""TimeInterpolator — 时间插值器接口"""
def getInterpolation(self, input_: float) -> float:
return input_
class AccelerateDecelerateInterpolator(TimeInterpolator):
"""AccelerateDecelerateInterpolator — 加速减速插值器"""
def getInterpolation(self, input_: float) -> float:
return (math.cos((input_ + 1) * math.pi) / 2.0) + 0.5
class AccelerateInterpolator(TimeInterpolator):
"""AccelerateInterpolator — 加速插值器"""
def __init__(self, factor: float = 1.0):
super().__init__()
self._factor = factor
def getInterpolation(self, input_: float) -> float:
if self._factor == 1.0:
return input_ * input_
return input_ ** (2.0 * self._factor)
class DecelerateInterpolator(TimeInterpolator):
"""DecelerateInterpolator — 减速插值器"""
def __init__(self, factor: float = 1.0):
super().__init__()
self._factor = factor
def getInterpolation(self, input_: float) -> float:
if self._factor == 1.0:
return 1.0 - (1.0 - input_) * (1.0 - input_)
return 1.0 - (1.0 - input_) ** (2.0 * self._factor)
class LinearInterpolator(TimeInterpolator):
"""LinearInterpolator — 线性插值器"""
def getInterpolation(self, input_: float) -> float:
return input_
class BounceInterpolator(TimeInterpolator):
"""BounceInterpolator — 弹跳插值器"""
def getInterpolation(self, input_: float) -> float:
t = input_
if t < 0.363636:
return 7.5625 * t * t
elif t < 0.727272:
t -= 0.545454
return 7.5625 * t * t + 0.75
elif t < 0.909090:
t -= 0.818181
return 7.5625 * t * t + 0.9375
else:
t -= 0.954545
return 7.5625 * t * t + 0.984375
class AnticipateInterpolator(TimeInterpolator):
"""AnticipateInterpolator — 预期插值器"""
def __init__(self, tension: float = 2.0):
super().__init__()
self._tension = tension
def getInterpolation(self, input_: float) -> float:
return input_ * input_ * ((self._tension + 1) * input_ - self._tension)
class OvershootInterpolator(TimeInterpolator):
"""OvershootInterpolator — 过冲插值器"""
def __init__(self, tension: float = 2.0):
super().__init__()
self._tension = tension
def getInterpolation(self, input_: float) -> float:
t = input_ - 1.0
return t * t * ((self._tension + 1) * t + self._tension) + 1.0
class AnticipateOvershootInterpolator(TimeInterpolator):
"""AnticipateOvershootInterpolator — 预期过冲插值器"""
def __init__(self, tension: float = 2.0, extraTension: float = 1.5):
super().__init__()
self._tension = tension
self._extra_tension = extraTension
def getInterpolation(self, input_: float) -> float:
if input_ < 0.5:
t = input_ * 2.0
return 0.5 * t * t * ((self._tension + 1) * t - self._tension)
else:
t = (input_ - 0.5) * 2.0 - 1.0
return 0.5 * (t * t * ((self._tension + 1) * t + self._tension) + 2.0)
class CycleInterpolator(TimeInterpolator):
"""CycleInterpolator — 周期插值器"""
def __init__(self, cycles: float = 1.0):
super().__init__()
self._cycles = cycles
def getInterpolation(self, input_: float) -> float:
return math.sin(2 * math.pi * self._cycles * input_)
class PathInterpolator(TimeInterpolator):
"""PathInterpolator — 路径插值器"""
def __init__(self, controlX1: float = 0.0, controlY1: float = 0.0,
controlX2: float = 1.0, controlY2: float = 1.0):
super().__init__()
self._cx1 = controlX1
self._cy1 = controlY1
self._cx2 = controlX2
self._cy2 = controlY2
def getInterpolation(self, input_: float) -> float:
# Cubic bezier approximation
t = input_
return (3 * self._cy1 * t * (1 - t) ** 2 +
3 * self._cy2 * t ** 2 * (1 - t) +
t ** 3)
# ═══════════════════════════════════════════════════════════════
# AnimatorListener
# ═══════════════════════════════════════════════════════════════
class AnimatorListener(Stub):
"""AnimatorListener — 动画监听器"""
def onAnimationStart(self, animation: "Animator"):
pass
def onAnimationEnd(self, animation: "Animator"):
pass
def onAnimationCancel(self, animation: "Animator"):
pass
def onAnimationRepeat(self, animation: "Animator"):
pass
class AnimatorPauseListener(Stub):
"""AnimatorPauseListener — 动画暂停监听器"""
def onAnimationPause(self, animation: "Animator"):
pass
def onAnimationResume(self, animation: "Animator"):
pass
# ═══════════════════════════════════════════════════════════════
# Animator
# ═══════════════════════════════════════════════════════════════
class Animator(Stub):
"""Animator — 动画基类"""
def __init__(self):
super().__init__()
self._duration: int = 300
self._start_delay: int = 0
self._interpolator: Optional[TimeInterpolator] = None
self._listeners: List[AnimatorListener] = []
self._pause_listeners: List[AnimatorPauseListener] = []
self._running: bool = False
self._started: bool = False
self._paused: bool = False
self._start_time: float = 0.0
def start(self):
self._running = True
self._started = True
self._start_time = _time.time() + self._start_delay / 1000.0
self._notify_start()
def end(self):
if self._running:
self._running = False
self._notify_end()
def cancel(self):
if self._running:
self._running = False
self._started = False
self._notify_cancel()
def pause(self):
if self._running and not self._paused:
self._paused = True
for l in self._pause_listeners:
l.onAnimationPause(self)
def resume(self):
if self._paused:
self._paused = False
for l in self._pause_listeners:
l.onAnimationResume(self)
def isRunning(self) -> bool:
return self._running
def isStarted(self) -> bool:
return self._started
def isPaused(self) -> bool:
return self._paused
def addListener(self, listener: AnimatorListener):
if listener not in self._listeners:
self._listeners.append(listener)
def removeListener(self, listener: AnimatorListener):
if listener in self._listeners:
self._listeners.remove(listener)
def getListeners(self) -> List[AnimatorListener]:
return list(self._listeners)
def addPauseListener(self, listener: AnimatorPauseListener):
if listener not in self._pause_listeners:
self._pause_listeners.append(listener)
def removePauseListener(self, listener: AnimatorPauseListener):
if listener in self._pause_listeners:
self._pause_listeners.remove(listener)
def setDuration(self, duration: int) -> "Animator":
self._duration = duration
return self
def getDuration(self) -> int:
return self._duration
def setStartDelay(self, startDelay: int) -> "Animator":
self._start_delay = startDelay
return self
def getStartDelay(self) -> int:
return self._start_delay
def setInterpolator(self, interpolator: TimeInterpolator):
self._interpolator = interpolator
def getInterpolator(self) -> Optional[TimeInterpolator]:
return self._interpolator
def clone(self) -> "Animator":
cloned = Animator()
cloned._duration = self._duration
cloned._start_delay = self._start_delay
cloned._interpolator = self._interpolator
return cloned
def _notify_start(self):
for l in self._listeners:
l.onAnimationStart(self)
def _notify_end(self):
for l in self._listeners:
l.onAnimationEnd(self)
def _notify_cancel(self):
for l in self._listeners:
l.onAnimationCancel(self)
def _notify_repeat(self):
for l in self._listeners:
l.onAnimationRepeat(self)
def toString(self) -> str:
return f"Animator@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# ValueAnimator.AnimatorUpdateListener
# ═══════════════════════════════════════════════════════════════
class ValueAnimator:
class AnimatorUpdateListener(Stub):
"""AnimatorUpdateListener — 值更新监听器"""
def onAnimationUpdate(self, animation: "ValueAnimator"):
pass
# ═══════════════════════════════════════════════════════════════
# ValueAnimator
# ═══════════════════════════════════════════════════════════════
class ValueAnimator(Animator):
"""ValueAnimator — 值动画"""
INFINITE = -1
RESTART = 1
REVERSE = 2
def __init__(self):
super().__init__()
self._values: List[Any] = []
self._animated_value: Any = None
self._animated_fraction: float = 0.0
self._repeat_count: int = 0
self._repeat_mode: int = self.RESTART
self._evaluator: Optional[TypeEvaluator] = None
self._update_listeners: List[ValueAnimator.AnimatorUpdateListener] = []
self._current_play_time: int = 0
self._reverse_direction: bool = False
self._property_name: Optional[str] = None
@staticmethod
def ofInt(*values: int) -> "ValueAnimator":
anim = ValueAnimator()
anim._values = list(values)
anim._evaluator = IntEvaluator()
return anim
@staticmethod
def ofFloat(*values: float) -> "ValueAnimator":
anim = ValueAnimator()
anim._values = list(values)
anim._evaluator = FloatEvaluator()
return anim
@staticmethod
def ofObject(*values: Any) -> "ValueAnimator":
anim = ValueAnimator()
anim._values = list(values)
return anim
def setIntValues(self, *values: int):
self._values = list(values)
def setFloatValues(self, *values: float):
self._values = list(values)
def setObjectValues(self, *values: Any):
self._values = list(values)
def getAnimatedValue(self) -> Any:
return self._animated_value
def getAnimatedFraction(self) -> float:
return self._animated_fraction
def setRepeatCount(self, count: int):
self._repeat_count = count
def getRepeatCount(self) -> int:
return self._repeat_count
def setRepeatMode(self, mode: int):
self._repeat_mode = mode
def getRepeatMode(self) -> int:
return self._repeat_mode
def setEvaluator(self, evaluator: TypeEvaluator):
self._evaluator = evaluator
def getEvaluator(self) -> Optional[TypeEvaluator]:
return self._evaluator
def setCurrentPlayTime(self, playTime: int):
self._current_play_time = playTime
if self._duration > 0:
self._animated_fraction = playTime / self._duration
self._evaluate()
def getCurrentPlayTime(self) -> int:
return self._current_play_time
def reverse(self):
self._reverse_direction = not self._reverse_direction
self.start()
def addUpdateListener(self, listener: ValueAnimator.AnimatorUpdateListener):
if listener not in self._update_listeners:
self._update_listeners.append(listener)
def removeUpdateListener(self, listener: ValueAnimator.AnimatorUpdateListener):
if listener in self._update_listeners:
self._update_listeners.remove(listener)
def removeAllUpdateListeners(self):
self._update_listeners.clear()
def start(self):
super().start()
if len(self._values) >= 2:
self._evaluate()
def _evaluate(self):
if len(self._values) >= 2 and self._evaluator:
fraction = self._animated_fraction
if self._interpolator:
fraction = self._interpolator.getInterpolation(fraction)
self._animated_value = self._evaluator.evaluate(
fraction, self._values[0], self._values[-1]
)
for l in self._update_listeners:
l.onAnimationUpdate(self)
def clone(self) -> "ValueAnimator":
cloned = ValueAnimator()
cloned._values = list(self._values)
cloned._duration = self._duration
cloned._start_delay = self._start_delay
cloned._repeat_count = self._repeat_count
cloned._repeat_mode = self._repeat_mode
cloned._evaluator = self._evaluator
cloned._interpolator = self._interpolator
return cloned
def toString(self) -> str:
return f"ValueAnimator@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# ObjectAnimator
# ═══════════════════════════════════════════════════════════════
class ObjectAnimator(ValueAnimator):
"""ObjectAnimator — 对象属性动画"""
def __init__(self):
super().__init__()
self._target: Any = None
self._property_name: Optional[str] = None
@staticmethod
def ofInt(target: Any, propertyName: str, *values: int) -> "ObjectAnimator":
anim = ObjectAnimator()
anim._target = target
anim._property_name = propertyName
anim._values = list(values)
anim._evaluator = IntEvaluator()
return anim
@staticmethod
def ofFloat(target: Any, propertyName: str, *values: float) -> "ObjectAnimator":
anim = ObjectAnimator()
anim._target = target
anim._property_name = propertyName
anim._values = list(values)
anim._evaluator = FloatEvaluator()
return anim
@staticmethod
def ofObject(target: Any, propertyName: str, *values: Any) -> "ObjectAnimator":
anim = ObjectAnimator()
anim._target = target
anim._property_name = propertyName
anim._values = list(values)
return anim
def setPropertyName(self, propertyName: str):
self._property_name = propertyName
def getPropertyName(self) -> Optional[str]:
return self._property_name
def getTarget(self) -> Any:
return self._target
def setTarget(self, target: Any):
self._target = target
def setProperty(self, property_: Any):
pass
def setupStartValues(self):
pass
def setupEndValues(self):
pass
def clone(self) -> "ObjectAnimator":
cloned = ObjectAnimator()
cloned._target = self._target
cloned._property_name = self._property_name
cloned._values = list(self._values)
cloned._duration = self._duration
cloned._start_delay = self._start_delay
cloned._evaluator = self._evaluator
cloned._interpolator = self._interpolator
return cloned
def toString(self) -> str:
return f"ObjectAnimator{{property={self._property_name}, target={self._target}}}"
# ═══════════════════════════════════════════════════════════════
# AnimatorSet
# ═══════════════════════════════════════════════════════════════
class AnimatorSet(Animator):
"""AnimatorSet — 动画集合"""
def __init__(self):
super().__init__()
self._children: List[Animator] = []
self._play_order: List[Animator] = []
def play(self, anim: Animator) -> "AnimatorSet.Builder":
return self.Builder(self, anim)
def playSequentially(self, *items: Animator):
self._children = list(items)
self._play_order = list(items)
def playTogether(self, *items: Animator):
self._children = list(items)
self._play_order = list(items)
def start(self):
super().start()
for anim in self._play_order:
anim.start()
def end(self):
super().end()
for anim in self._play_order:
anim.end()
def cancel(self):
super().cancel()
for anim in self._play_order:
anim.cancel()
class Builder(Stub):
"""AnimatorSet.Builder — 构建器"""
def __init__(self, parent: "AnimatorSet", anim: Animator):
super().__init__()
self._parent = parent
self._current = anim
def with_(self, anim: Animator) -> "AnimatorSet.Builder":
self._parent._play_order.append(anim)
return self
def before(self, anim: Animator) -> "AnimatorSet.Builder":
self._parent._play_order.append(anim)
return self
def after(self, anim: Animator) -> "AnimatorSet.Builder":
idx = self._parent._play_order.index(self._current) if self._current in self._parent._play_order else -1
if idx >= 0:
self._parent._play_order.insert(idx + 1, anim)
else:
self._parent._play_order.append(anim)
return self
def after(self, delay: int) -> "AnimatorSet.Builder":
return self
def toString(self) -> str:
return f"AnimatorSet{{{len(self._children)} animations}}"
# ═══════════════════════════════════════════════════════════════
# TimeAnimator
# ═══════════════════════════════════════════════════════════════
class TimeAnimator(ValueAnimator):
"""TimeAnimator — 时间动画"""
class TimeListener(Stub):
"""TimeListener — 时间监听器"""
def onTimeUpdate(self, animation: "TimeAnimator", elapsedTime: int, totalTime: int):
pass
def __init__(self):
super().__init__()
self._time_listener: Optional[TimeAnimator.TimeListener] = None
self._elapsed_time: int = 0
self._total_time: int = 0
def setTimeListener(self, listener: TimeAnimator.TimeListener):
self._time_listener = listener
def start(self):
super().start()
if self._time_listener:
self._time_listener.onTimeUpdate(self, self._elapsed_time, self._total_time)
def toString(self) -> str:
return f"TimeAnimator@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# Keyframe
# ═══════════════════════════════════════════════════════════════
class Keyframe(Stub):
"""Keyframe — 关键帧"""
def __init__(self, fraction: float):
super().__init__()
self._fraction: float = fraction
self._value: Any = None
self._type: Optional[type] = None
self._interpolator: Optional[TimeInterpolator] = None
@staticmethod
def ofInt(fraction: float, value: int) -> "Keyframe":
kf = Keyframe(fraction)
kf._value = value
kf._type = int
return kf
@staticmethod
def ofFloat(fraction: float, value: float) -> "Keyframe":
kf = Keyframe(fraction)
kf._value = value
kf._type = float
return kf
@staticmethod
def ofObject(fraction: float, value: Any = None) -> "Keyframe":
kf = Keyframe(fraction)
kf._value = value
return kf
def setValue(self, value: Any):
self._value = value
def getValue(self) -> Any:
return self._value
def setFraction(self, fraction: float):
self._fraction = fraction
def getFraction(self) -> float:
return self._fraction
def getType(self) -> Optional[type]:
return self._type
def setInterpolator(self, interpolator: Optional[TimeInterpolator]):
self._interpolator = interpolator
def getInterpolator(self) -> Optional[TimeInterpolator]:
return self._interpolator
def clone(self) -> "Keyframe":
kf = Keyframe(self._fraction)
kf._value = self._value
kf._type = self._type
kf._interpolator = self._interpolator
return kf
def toString(self) -> str:
return f"Keyframe{{fraction={self._fraction}, value={self._value}}}"
# ═══════════════════════════════════════════════════════════════
# PropertyValuesHolder
# ═══════════════════════════════════════════════════════════════
class PropertyValuesHolder(Stub):
"""PropertyValuesHolder — 属性值持有者"""
def __init__(self):
super().__init__()
self._property_name: str = ""
self._values: List[Any] = []
self._animated_value: Any = None
self._evaluator: Optional[TypeEvaluator] = None
self._keyframes: List[Keyframe] = []
@staticmethod
def ofInt(propertyName: str, *values: int) -> "PropertyValuesHolder":
holder = PropertyValuesHolder()
holder._property_name = propertyName
holder._values = list(values)
return holder
@staticmethod
def ofFloat(propertyName: str, *values: float) -> "PropertyValuesHolder":
holder = PropertyValuesHolder()
holder._property_name = propertyName
holder._values = list(values)
return holder
@staticmethod
def ofObject(propertyName: str, *values: Any) -> "PropertyValuesHolder":
holder = PropertyValuesHolder()
holder._property_name = propertyName
holder._values = list(values)
return holder
@staticmethod
def ofKeyframes(propertyName: str, *keyframes: Keyframe) -> "PropertyValuesHolder":
holder = PropertyValuesHolder()
holder._property_name = propertyName
holder._keyframes = list(keyframes)
return holder
def setPropertyName(self, propertyName: str):
self._property_name = propertyName
def getPropertyName(self) -> str:
return self._property_name
def getAnimatedValue(self) -> Any:
return self._animated_value
def setEvaluator(self, evaluator: TypeEvaluator):
self._evaluator = evaluator
def clone(self) -> "PropertyValuesHolder":
holder = PropertyValuesHolder()
holder._property_name = self._property_name
holder._values = list(self._values)
holder._keyframes = list(self._keyframes)
holder._evaluator = self._evaluator
return holder
def toString(self) -> str:
return f"PropertyValuesHolder{{property={self._property_name}}}"
# ═══════════════════════════════════════════════════════════════
# TypeConverter
# ═══════════════════════════════════════════════════════════════
class TypeConverter(Stub):
"""TypeConverter — 类型转换器"""
def convert(self, value: Any) -> Any:
return value
# ═══════════════════════════════════════════════════════════════
# LayoutTransition
# ═══════════════════════════════════════════════════════════════
class LayoutTransition(Stub):
"""LayoutTransition — 布局过渡动画"""
APPEARING = 0
CHANGE_APPEARING = 1
CHANGE_DISAPPEARING = 2
DISAPPEARING = 3
CHANGING = 4
def __init__(self):
super().__init__()
self._animators: Dict[int, Optional[Animator]] = {
self.APPEARING: None,
self.CHANGE_APPEARING: None,
self.CHANGE_DISAPPEARING: None,
self.DISAPPEARING: None,
self.CHANGING: None,
}
def setAnimator(self, transitionType: int, animator: Animator):
self._animators[transitionType] = animator
def getAnimator(self, transitionType: int) -> Optional[Animator]:
return self._animators.get(transitionType)
def startTransition(self, container: Any, transitionType: int):
pass
def endTransition(self, transitionType: int):
pass
def toString(self) -> str:
return f"LayoutTransition@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# StateListAnimator
# ═══════════════════════════════════════════════════════════════
class StateListAnimator(Stub):
"""StateListAnimator — 状态列表动画"""
def __init__(self):
super().__init__()
self._tuples: List[Tuple[List[int], Animator]] = []
self._target: Any = None
def addState(self, specs: List[int], animator: Animator):
self._tuples.append((specs, animator))
def setTarget(self, target: Any):
self._target = target
def clone(self) -> "StateListAnimator":
cloned = StateListAnimator()
cloned._tuples = list(self._tuples)
return cloned
def toString(self) -> str:
return f"StateListAnimator{{{len(self._tuples)} states}}"
# ═══════════════════════════════════════════════════════════════
# __all__
# ═══════════════════════════════════════════════════════════════
__all__ = [
"Animator",
"ValueAnimator",
"ObjectAnimator",
"AnimatorSet",
"TimeAnimator",
"AnimatorListener",
"AnimatorPauseListener",
"TypeEvaluator",
"FloatEvaluator",
"IntEvaluator",
"PointFEvaluator",
"RectEvaluator",
"ArgbEvaluator",
"TypeConverter",
"Keyframe",
"PropertyValuesHolder",
"LayoutTransition",
"StateListAnimator",
"TimeInterpolator",
"AccelerateDecelerateInterpolator",
"AccelerateInterpolator",
"AnticipateInterpolator",
"AnticipateOvershootInterpolator",
"BounceInterpolator",
"CycleInterpolator",
"DecelerateInterpolator",
"LinearInterpolator",
"OvershootInterpolator",
"PathInterpolator",
]