feat: Android-pyApi v1.0 - 全面翻译 Android SDK API 为 Python
52 个模块覆盖 Android + Java + org.json 标准库
This commit is contained in:
commit
bfe27fdc08
104 files changed
+58750
No files matched your search
@@ -0,0 +1,935 @@
|
||||
"""
|
||||
Android View Animation 组件 — Animation, AnimationSet, Interpolators,
|
||||
AnimationUtils, Transformation 等
|
||||
方法签名完全对齐 Android SDK
|
||||
"""
|
||||
|
||||
import math
|
||||
import sys
|
||||
import time
|
||||
from typing import Any, Callable, Dict, List, Optional, Tuple
|
||||
|
||||
from .._core import Stub, AndroidOnlyError, android_context
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Interpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Interpolator(Stub):
|
||||
"""Interpolator — 插值器接口"""
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
return input
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AccelerateInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AccelerateInterpolator(Interpolator):
|
||||
"""AccelerateInterpolator — 加速插值器(先慢后快)"""
|
||||
|
||||
def __init__(self, factor: float = 1.0):
|
||||
super().__init__()
|
||||
self._factor = factor
|
||||
self._double_factor = 2.0 * factor
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
if self._factor == 1.0:
|
||||
return input * input
|
||||
return input ** (self._double_factor)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# DecelerateInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class DecelerateInterpolator(Interpolator):
|
||||
"""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)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AccelerateDecelerateInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AccelerateDecelerateInterpolator(Interpolator):
|
||||
"""AccelerateDecelerateInterpolator — 加速减速插值器"""
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
return float(math.cos((input + 1) * math.pi) / 2.0 + 0.5)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# LinearInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class LinearInterpolator(Interpolator):
|
||||
"""LinearInterpolator — 线性插值器"""
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
return input
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# OvershootInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class OvershootInterpolator(Interpolator):
|
||||
"""OvershootInterpolator — 超出插值器(越过目标再回弹)"""
|
||||
|
||||
def __init__(self, tension: float = 2.0):
|
||||
super().__init__()
|
||||
self._tension = tension
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
input -= 1.0
|
||||
return input * input * ((self._tension + 1) * input + self._tension) + 1.0
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AnticipateInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AnticipateInterpolator(Interpolator):
|
||||
"""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)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AnticipateOvershootInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AnticipateOvershootInterpolator(Interpolator):
|
||||
"""AnticipateOvershootInterpolator — 预判超出插值器"""
|
||||
|
||||
def __init__(self, tension: float = 2.0, extra_tension: float = 1.5):
|
||||
super().__init__()
|
||||
self._tension = tension
|
||||
self._extra_tension = extra_tension
|
||||
|
||||
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 * 2.0 - 2.0
|
||||
return 0.5 * (t * t * ((self._tension + 1) * t + self._tension) + 2.0)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# BounceInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class BounceInterpolator(Interpolator):
|
||||
"""BounceInterpolator — 弹跳插值器"""
|
||||
|
||||
@staticmethod
|
||||
def _bounce(t: float) -> float:
|
||||
t2 = t * t
|
||||
return t2 * 8.0
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
if input < 0.3535:
|
||||
return BounceInterpolator._bounce(input)
|
||||
elif input < 0.7408:
|
||||
return BounceInterpolator._bounce(input - 0.54719) + 0.7
|
||||
elif input < 0.9644:
|
||||
return BounceInterpolator._bounce(input - 0.8526) + 0.9
|
||||
else:
|
||||
return BounceInterpolator._bounce(input - 1.0435) + 0.95
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# CycleInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class CycleInterpolator(Interpolator):
|
||||
"""CycleInterpolator — 周期插值器(正弦循环)"""
|
||||
|
||||
def __init__(self, cycles: float = 1.0):
|
||||
super().__init__()
|
||||
self._cycles = cycles
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
return float(math.sin(2.0 * math.pi * self._cycles * input))
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# PathInterpolator
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class PathInterpolator(Interpolator):
|
||||
"""PathInterpolator — 路径插值器"""
|
||||
|
||||
def __init__(self, control_x1: float = 0.0, control_y1: float = 0.0,
|
||||
control_x2: float = 1.0, control_y2: float = 1.0):
|
||||
super().__init__()
|
||||
self._control_x1 = control_x1
|
||||
self._control_y1 = control_y1
|
||||
self._control_x2 = control_x2
|
||||
self._control_y2 = control_y2
|
||||
|
||||
def getInterpolation(self, input: float) -> float:
|
||||
return self._cubic_bezier(input)
|
||||
|
||||
def _cubic_bezier(self, t: float) -> float:
|
||||
u = 1.0 - t
|
||||
return (3.0 * u * u * t * self._control_y1 +
|
||||
3.0 * u * t * t * self._control_y2 +
|
||||
t * t * t)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Transformation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Transformation(Stub):
|
||||
"""Transformation — 动画变换矩阵"""
|
||||
|
||||
TYPE_IDENTITY = 0
|
||||
TYPE_ALPHA = 1
|
||||
TYPE_BOTH = 2
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._alpha: float = 1.0
|
||||
self._matrix: Any = None # 占位,实际 Android 为 Matrix 对象
|
||||
self._transformation_type: int = Transformation.TYPE_IDENTITY
|
||||
|
||||
def getAlpha(self) -> float:
|
||||
return self._alpha
|
||||
|
||||
def setAlpha(self, alpha: float):
|
||||
self._alpha = alpha
|
||||
|
||||
def getMatrix(self) -> Any:
|
||||
return self._matrix
|
||||
|
||||
def setMatrix(self, matrix: Any):
|
||||
self._matrix = matrix
|
||||
|
||||
def setTransformationType(self, transformation_type: int):
|
||||
self._transformation_type = transformation_type
|
||||
|
||||
def getTransformationType(self) -> int:
|
||||
return self._transformation_type
|
||||
|
||||
def clear(self):
|
||||
self._alpha = 1.0
|
||||
self._matrix = None
|
||||
self._transformation_type = Transformation.TYPE_IDENTITY
|
||||
|
||||
def compose(self, other: "Transformation"):
|
||||
if other is None:
|
||||
return
|
||||
self._alpha *= other._alpha
|
||||
if self._matrix is None:
|
||||
self._matrix = other._matrix
|
||||
elif other._matrix is not None:
|
||||
pass # 占位:矩阵乘法
|
||||
self._transformation_type = max(self._transformation_type,
|
||||
other._transformation_type)
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"Transformation(alpha={self._alpha}, "
|
||||
f"type={self._transformation_type})")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Animation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class Animation(Stub):
|
||||
"""Animation — 动画基类"""
|
||||
|
||||
INFINITE = -1
|
||||
RESTART = 1
|
||||
REVERSE = 2
|
||||
|
||||
ABSOLUTE = 0
|
||||
RELATIVE_TO_SELF = 1
|
||||
RELATIVE_TO_PARENT = 2
|
||||
|
||||
START_ON_FIRST_FRAME = -1
|
||||
|
||||
class AnimationListener(Stub):
|
||||
"""AnimationListener — 动画监听器"""
|
||||
|
||||
def onAnimationStart(self, animation: "Animation"):
|
||||
pass
|
||||
|
||||
def onAnimationEnd(self, animation: "Animation"):
|
||||
pass
|
||||
|
||||
def onAnimationRepeat(self, animation: "Animation"):
|
||||
pass
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self._duration: int = 0
|
||||
self._start_offset: int = 0
|
||||
self._repeat_count: int = 0
|
||||
self._repeat_mode: int = Animation.RESTART
|
||||
self._fill_before: bool = False
|
||||
self._fill_after: bool = False
|
||||
self._fill_enabled: bool = False
|
||||
self._z_adjustment: int = 0
|
||||
self._interpolator: Optional[Interpolator] = None
|
||||
self._listener: Optional["Animation.AnimationListener"] = None
|
||||
self._start_time: Optional[int] = None
|
||||
self._started: bool = False
|
||||
self._ended: bool = False
|
||||
self._cycle: float = 0.0
|
||||
self._current_repeat: int = 0
|
||||
self._initialized: bool = False
|
||||
self._scale_factor: float = 1.0
|
||||
self._paused: bool = False
|
||||
self._more: bool = True
|
||||
|
||||
def start(self):
|
||||
self._start_time = self._current_time_millis()
|
||||
self._started = True
|
||||
self._ended = False
|
||||
self._current_repeat = 0
|
||||
self._more = True
|
||||
if self._listener:
|
||||
self._listener.onAnimationStart(self)
|
||||
|
||||
def startNow(self):
|
||||
self.start()
|
||||
|
||||
def cancel(self):
|
||||
self._ended = True
|
||||
self._more = False
|
||||
|
||||
def reset(self):
|
||||
self._start_time = None
|
||||
self._started = False
|
||||
self._ended = False
|
||||
self._current_repeat = 0
|
||||
self._cycle = 0.0
|
||||
self._more = True
|
||||
self._initialized = False
|
||||
|
||||
def setDuration(self, duration_millis: int):
|
||||
self._duration = duration_millis
|
||||
|
||||
def getDuration(self) -> int:
|
||||
return self._duration
|
||||
|
||||
def setStartOffset(self, start_offset: int):
|
||||
self._start_offset = start_offset
|
||||
|
||||
def getStartOffset(self) -> int:
|
||||
return self._start_offset
|
||||
|
||||
def setRepeatCount(self, repeat_count: int):
|
||||
self._repeat_count = repeat_count
|
||||
|
||||
def getRepeatCount(self) -> int:
|
||||
return self._repeat_count
|
||||
|
||||
def setRepeatMode(self, repeat_mode: int):
|
||||
self._repeat_mode = repeat_mode
|
||||
|
||||
def getRepeatMode(self) -> int:
|
||||
return self._repeat_mode
|
||||
|
||||
def setInterpolator(self, interpolator: Optional[Interpolator]):
|
||||
self._interpolator = interpolator
|
||||
|
||||
def getInterpolator(self) -> Optional[Interpolator]:
|
||||
return self._interpolator
|
||||
|
||||
def setAnimationListener(self, listener: "Animation.AnimationListener"):
|
||||
self._listener = listener
|
||||
|
||||
def getAnimationListener(self) -> Optional["Animation.AnimationListener"]:
|
||||
return self._listener
|
||||
|
||||
def getTransformation(self, current_time: int,
|
||||
out_transformation: Transformation) -> bool:
|
||||
if self._start_time is None:
|
||||
self._start_time = current_time
|
||||
|
||||
elapsed = current_time - self._start_time - self._start_offset
|
||||
if elapsed < 0:
|
||||
out_transformation.clear()
|
||||
return True
|
||||
|
||||
duration = self._duration
|
||||
if duration == 0:
|
||||
duration = 1
|
||||
|
||||
normalized = elapsed / duration
|
||||
|
||||
if normalized >= 1.0:
|
||||
if self._current_repeat < self._repeat_count or self._repeat_count == self.INFINITE:
|
||||
if self._repeat_mode == Animation.REVERSE:
|
||||
normalized = 0.0
|
||||
else:
|
||||
normalized = 0.0
|
||||
self._current_repeat += 1
|
||||
if self._listener:
|
||||
self._listener.onAnimationRepeat(self)
|
||||
else:
|
||||
normalized = 1.0
|
||||
self._ended = True
|
||||
self._more = False
|
||||
self._apply_transformation(1.0, out_transformation)
|
||||
if self._listener:
|
||||
self._listener.onAnimationEnd(self)
|
||||
return False
|
||||
|
||||
if normalized > 1.0:
|
||||
normalized = 1.0
|
||||
|
||||
if self._interpolator:
|
||||
interpolated = self._interpolator.getInterpolation(normalized)
|
||||
else:
|
||||
interpolated = normalized
|
||||
|
||||
self._cycle = normalized
|
||||
self._apply_transformation(interpolated, out_transformation)
|
||||
return self._more
|
||||
|
||||
def _apply_transformation(self, interpolated_time: float, t: Transformation):
|
||||
pass
|
||||
|
||||
def hasEnded(self) -> bool:
|
||||
return self._ended
|
||||
|
||||
def hasStarted(self) -> bool:
|
||||
return self._started
|
||||
|
||||
def setFillBefore(self, fill_before: bool):
|
||||
self._fill_before = fill_before
|
||||
|
||||
def getFillBefore(self) -> bool:
|
||||
return self._fill_before
|
||||
|
||||
def setFillAfter(self, fill_after: bool):
|
||||
self._fill_after = fill_after
|
||||
|
||||
def getFillAfter(self) -> bool:
|
||||
return self._fill_after
|
||||
|
||||
def setFillEnabled(self, fill_enabled: bool):
|
||||
self._fill_enabled = fill_enabled
|
||||
|
||||
def getFillEnabled(self) -> bool:
|
||||
return self._fill_enabled
|
||||
|
||||
def setZAdjustment(self, z_adjustment: int):
|
||||
self._z_adjustment = z_adjustment
|
||||
|
||||
def getZAdjustment(self) -> int:
|
||||
return self._z_adjustment
|
||||
|
||||
def willChangeBounds(self) -> bool:
|
||||
return True
|
||||
|
||||
def willChangeTransformationMatrix(self) -> bool:
|
||||
return True
|
||||
|
||||
def initialize(self, width: int, height: int, parent_width: int, parent_height: int):
|
||||
self._initialized = True
|
||||
|
||||
def restrictDuration(self, duration_millis: int):
|
||||
if self._duration > duration_millis:
|
||||
self._duration = duration_millis
|
||||
|
||||
def scaleCurrentDuration(self, scale: float):
|
||||
self._duration = int(self._duration * scale)
|
||||
|
||||
@staticmethod
|
||||
def _current_time_millis() -> int:
|
||||
return int(time.time() * 1000)
|
||||
|
||||
def toString(self) -> str:
|
||||
return (f"Animation(duration={self._duration}, "
|
||||
f"repeatCount={self._repeat_count}, "
|
||||
f"started={self._started})")
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AlphaAnimation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AlphaAnimation(Animation):
|
||||
"""AlphaAnimation — 透明度动画"""
|
||||
|
||||
def __init__(self, from_alpha: float, to_alpha: float):
|
||||
super().__init__()
|
||||
self._from_alpha = from_alpha
|
||||
self._to_alpha = to_alpha
|
||||
|
||||
def _apply_transformation(self, interpolated_time: float, t: Transformation):
|
||||
alpha = self._from_alpha + (self._to_alpha - self._from_alpha) * interpolated_time
|
||||
t.setAlpha(alpha)
|
||||
|
||||
def getFromAlpha(self) -> float:
|
||||
return self._from_alpha
|
||||
|
||||
def getToAlpha(self) -> float:
|
||||
return self._to_alpha
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# ScaleAnimation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class ScaleAnimation(Animation):
|
||||
"""ScaleAnimation — 缩放动画"""
|
||||
|
||||
def __init__(self, from_x: float, to_x: float, from_y: float, to_y: float,
|
||||
pivot_x: float = 0.0, pivot_y: float = 0.0,
|
||||
pivot_x_type: int = Animation.ABSOLUTE,
|
||||
pivot_y_type: int = Animation.ABSOLUTE):
|
||||
super().__init__()
|
||||
self._from_x = from_x
|
||||
self._to_x = to_x
|
||||
self._from_y = from_y
|
||||
self._to_y = to_y
|
||||
self._pivot_x = pivot_x
|
||||
self._pivot_y = pivot_y
|
||||
self._pivot_x_type = pivot_x_type
|
||||
self._pivot_y_type = pivot_y_type
|
||||
|
||||
def _apply_transformation(self, interpolated_time: float, t: Transformation):
|
||||
sx = self._from_x + (self._to_x - self._from_x) * interpolated_time
|
||||
sy = self._from_y + (self._to_y - self._from_y) * interpolated_time
|
||||
# 占位:Matrix 的缩放操作
|
||||
if t.getMatrix() is not None:
|
||||
pass
|
||||
|
||||
def getFromX(self) -> float:
|
||||
return self._from_x
|
||||
|
||||
def getToX(self) -> float:
|
||||
return self._to_x
|
||||
|
||||
def getFromY(self) -> float:
|
||||
return self._from_y
|
||||
|
||||
def getToY(self) -> float:
|
||||
return self._to_y
|
||||
|
||||
def getPivotX(self) -> float:
|
||||
return self._pivot_x
|
||||
|
||||
def getPivotY(self) -> float:
|
||||
return self._pivot_y
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# TranslateAnimation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class TranslateAnimation(Animation):
|
||||
"""TranslateAnimation — 平移动画"""
|
||||
|
||||
def __init__(self, from_x: float, to_x: float, from_y: float, to_y: float,
|
||||
from_x_type: int = Animation.ABSOLUTE,
|
||||
to_x_type: int = Animation.ABSOLUTE,
|
||||
from_y_type: int = Animation.ABSOLUTE,
|
||||
to_y_type: int = Animation.ABSOLUTE):
|
||||
super().__init__()
|
||||
self._from_x = from_x
|
||||
self._to_x = to_x
|
||||
self._from_y = from_y
|
||||
self._to_y = to_y
|
||||
self._from_x_type = from_x_type
|
||||
self._to_x_type = to_x_type
|
||||
self._from_y_type = from_y_type
|
||||
self._to_y_type = to_y_type
|
||||
|
||||
def _apply_transformation(self, interpolated_time: float, t: Transformation):
|
||||
dx = self._from_x + (self._to_x - self._from_x) * interpolated_time
|
||||
dy = self._from_y + (self._to_y - self._from_y) * interpolated_time
|
||||
if t.getMatrix() is not None:
|
||||
pass
|
||||
|
||||
def getFromX(self) -> float:
|
||||
return self._from_x
|
||||
|
||||
def getToX(self) -> float:
|
||||
return self._to_x
|
||||
|
||||
def getFromY(self) -> float:
|
||||
return self._from_y
|
||||
|
||||
def getToY(self) -> float:
|
||||
return self._to_y
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# RotateAnimation
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class RotateAnimation(Animation):
|
||||
"""RotateAnimation — 旋转动画"""
|
||||
|
||||
def __init__(self, from_degrees: float, to_degrees: float,
|
||||
pivot_x: float = 0.0, pivot_y: float = 0.0,
|
||||
pivot_x_type: int = Animation.ABSOLUTE,
|
||||
pivot_y_type: int = Animation.ABSOLUTE):
|
||||
super().__init__()
|
||||
self._from_degrees = from_degrees
|
||||
self._to_degrees = to_degrees
|
||||
self._pivot_x = pivot_x
|
||||
self._pivot_y = pivot_y
|
||||
self._pivot_x_type = pivot_x_type
|
||||
self._pivot_y_type = pivot_y_type
|
||||
|
||||
def _apply_transformation(self, interpolated_time: float, t: Transformation):
|
||||
degrees = self._from_degrees + (self._to_degrees - self._from_degrees) * interpolated_time
|
||||
if t.getMatrix() is not None:
|
||||
pass
|
||||
|
||||
def getFromDegrees(self) -> float:
|
||||
return self._from_degrees
|
||||
|
||||
def getToDegrees(self) -> float:
|
||||
return self._to_degrees
|
||||
|
||||
def getPivotX(self) -> float:
|
||||
return self._pivot_x
|
||||
|
||||
def getPivotY(self) -> float:
|
||||
return self._pivot_y
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AnimationSet
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AnimationSet(Animation):
|
||||
"""AnimationSet — 动画集合"""
|
||||
|
||||
def __init__(self, share_interpolator: bool = True):
|
||||
super().__init__()
|
||||
self._share_interpolator = share_interpolator
|
||||
self._animations: List[Animation] = []
|
||||
|
||||
def addAnimation(self, animation: Animation):
|
||||
self._animations.append(animation)
|
||||
if self._share_interpolator and self._interpolator:
|
||||
animation.setInterpolator(self._interpolator)
|
||||
|
||||
def getAnimations(self) -> List[Animation]:
|
||||
return list(self._animations)
|
||||
|
||||
def setDuration(self, duration_millis: int):
|
||||
super().setDuration(duration_millis)
|
||||
for anim in self._animations:
|
||||
anim.setDuration(duration_millis)
|
||||
|
||||
def setFillAfter(self, fill_after: bool):
|
||||
super().setFillAfter(fill_after)
|
||||
for anim in self._animations:
|
||||
anim.setFillAfter(fill_after)
|
||||
|
||||
def setFillBefore(self, fill_before: bool):
|
||||
super().setFillBefore(fill_before)
|
||||
for anim in self._animations:
|
||||
anim.setFillBefore(fill_before)
|
||||
|
||||
def setRepeatMode(self, repeat_mode: int):
|
||||
super().setRepeatMode(repeat_mode)
|
||||
for anim in self._animations:
|
||||
anim.setRepeatMode(repeat_mode)
|
||||
|
||||
def setRepeatCount(self, repeat_count: int):
|
||||
super().setRepeatCount(repeat_count)
|
||||
for anim in self._animations:
|
||||
anim.setRepeatCount(repeat_count)
|
||||
|
||||
def setStartOffset(self, start_offset: int):
|
||||
super().setStartOffset(start_offset)
|
||||
for anim in self._animations:
|
||||
anim.setStartOffset(start_offset)
|
||||
|
||||
def setInterpolator(self, interpolator: Optional[Interpolator]):
|
||||
super().setInterpolator(interpolator)
|
||||
if self._share_interpolator:
|
||||
for anim in self._animations:
|
||||
anim.setInterpolator(interpolator)
|
||||
|
||||
def start(self):
|
||||
super().start()
|
||||
for anim in self._animations:
|
||||
anim.start()
|
||||
|
||||
def reset(self):
|
||||
super().reset()
|
||||
for anim in self._animations:
|
||||
anim.reset()
|
||||
|
||||
def cancel(self):
|
||||
super().cancel()
|
||||
for anim in self._animations:
|
||||
anim.cancel()
|
||||
|
||||
def getTransformation(self, current_time: int,
|
||||
out_transformation: Transformation) -> bool:
|
||||
more = False
|
||||
for anim in self._animations:
|
||||
local_t = Transformation()
|
||||
if anim.getTransformation(current_time, local_t):
|
||||
more = True
|
||||
out_transformation.compose(local_t)
|
||||
return more
|
||||
|
||||
def initialize(self, width: int, height: int, parent_width: int, parent_height: int):
|
||||
super().initialize(width, height, parent_width, parent_height)
|
||||
for anim in self._animations:
|
||||
anim.initialize(width, height, parent_width, parent_height)
|
||||
|
||||
def willChangeBounds(self) -> bool:
|
||||
for anim in self._animations:
|
||||
if anim.willChangeBounds():
|
||||
return True
|
||||
return False
|
||||
|
||||
def willChangeTransformationMatrix(self) -> bool:
|
||||
for anim in self._animations:
|
||||
if anim.willChangeTransformationMatrix():
|
||||
return True
|
||||
return False
|
||||
|
||||
def getAnimations(self) -> List[Animation]:
|
||||
return list(self._animations)
|
||||
|
||||
def restrictDuration(self, duration_millis: int):
|
||||
super().restrictDuration(duration_millis)
|
||||
for anim in self._animations:
|
||||
anim.restrictDuration(duration_millis)
|
||||
|
||||
def scaleCurrentDuration(self, scale: float):
|
||||
super().scaleCurrentDuration(scale)
|
||||
for anim in self._animations:
|
||||
anim.scaleCurrentDuration(scale)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# Animation.AnimationListener (已定义在 Animation 类中)
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
# Animation.AnimationListener is defined inside the Animation class above
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# AnimationUtils
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class AnimationUtils(Stub):
|
||||
"""AnimationUtils — 动画工具类"""
|
||||
|
||||
@staticmethod
|
||||
def loadAnimation(context: Any, id: int) -> Animation:
|
||||
"""加载动画资源(占位实现)"""
|
||||
sys.stderr.write(f"[AnimationUtils] loadAnimation: id={id}\n")
|
||||
return Animation()
|
||||
|
||||
@staticmethod
|
||||
def makeInAnimation(context: Any, from_left: bool) -> Animation:
|
||||
"""创建进入动画"""
|
||||
anim = AlphaAnimation(0.0, 1.0)
|
||||
anim.setDuration(300)
|
||||
return anim
|
||||
|
||||
@staticmethod
|
||||
def makeOutAnimation(context: Any, to_left: bool) -> Animation:
|
||||
"""创建退出动画"""
|
||||
anim = AlphaAnimation(1.0, 0.0)
|
||||
anim.setDuration(300)
|
||||
return anim
|
||||
|
||||
@staticmethod
|
||||
def makeInChildBottomAnimation(context: Any) -> Animation:
|
||||
"""创建子视图从底部进入动画"""
|
||||
anim = TranslateAnimation(0, 0, 1.0, 0.0,
|
||||
from_x_type=Animation.RELATIVE_TO_SELF,
|
||||
to_x_type=Animation.RELATIVE_TO_SELF,
|
||||
from_y_type=Animation.RELATIVE_TO_SELF,
|
||||
to_y_type=Animation.RELATIVE_TO_SELF)
|
||||
anim.setDuration(300)
|
||||
return anim
|
||||
|
||||
@staticmethod
|
||||
def currentAnimationTimeMillis() -> int:
|
||||
return int(time.time() * 1000)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# LayoutAnimationController
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class LayoutAnimationController(Stub):
|
||||
"""LayoutAnimationController — 布局动画控制器"""
|
||||
|
||||
ORDER_NORMAL = 0
|
||||
ORDER_REVERSE = 1
|
||||
ORDER_RANDOM = 2
|
||||
|
||||
def __init__(self, animation: Optional[Animation] = None):
|
||||
super().__init__()
|
||||
self._animation: Optional[Animation] = animation
|
||||
self._delay: float = 0.5
|
||||
self._order: int = LayoutAnimationController.ORDER_NORMAL
|
||||
self._initialized: bool = False
|
||||
self._max_delay: int = 0
|
||||
|
||||
def setAnimation(self, animation: Animation):
|
||||
self._animation = animation
|
||||
|
||||
def getAnimation(self) -> Optional[Animation]:
|
||||
return self._animation
|
||||
|
||||
def setOrder(self, order: int):
|
||||
self._order = order
|
||||
|
||||
def getOrder(self) -> int:
|
||||
return self._order
|
||||
|
||||
def setDelay(self, delay: float):
|
||||
self._delay = delay
|
||||
|
||||
def getDelay(self) -> float:
|
||||
return self._delay
|
||||
|
||||
def getDelayForView(self, view: Any) -> int:
|
||||
if self._order == LayoutAnimationController.ORDER_NORMAL:
|
||||
return 0
|
||||
elif self._order == LayoutAnimationController.ORDER_REVERSE:
|
||||
return 0
|
||||
elif self._order == LayoutAnimationController.ORDER_RANDOM:
|
||||
import random
|
||||
return int(random.random() * self._max_delay)
|
||||
return 0
|
||||
|
||||
def willOverlap(self) -> bool:
|
||||
return self._delay < 1.0
|
||||
|
||||
def start(self):
|
||||
self._initialized = True
|
||||
|
||||
def isDone(self) -> bool:
|
||||
return True
|
||||
|
||||
def getAnimationForView(self, view: Any) -> Optional[Animation]:
|
||||
return self._animation
|
||||
|
||||
def setInitialized(self, initialized: bool):
|
||||
self._initialized = initialized
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# GridLayoutAnimationController
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
class GridLayoutAnimationController(LayoutAnimationController):
|
||||
"""GridLayoutAnimationController — 网格布局动画控制器"""
|
||||
|
||||
DIRECTION_LEFT_TO_RIGHT = 0x0
|
||||
DIRECTION_RIGHT_TO_LEFT = 0x1
|
||||
DIRECTION_TOP_TO_BOTTOM = 0x2
|
||||
DIRECTION_BOTTOM_TO_TOP = 0x3
|
||||
DIRECTION_HORIZONTAL_MASK = 0x1
|
||||
DIRECTION_VERTICAL_MASK = 0x2
|
||||
|
||||
def __init__(self, animation: Optional[Animation] = None):
|
||||
super().__init__(animation)
|
||||
self._column_delay: float = 0.5
|
||||
self._row_delay: float = 0.5
|
||||
self._direction: int = GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT
|
||||
self._columns: int = 1
|
||||
self._rows: int = 1
|
||||
|
||||
def setColumnDelay(self, column_delay: float):
|
||||
self._column_delay = column_delay
|
||||
|
||||
def getColumnDelay(self) -> float:
|
||||
return self._column_delay
|
||||
|
||||
def setRowDelay(self, row_delay: float):
|
||||
self._row_delay = row_delay
|
||||
|
||||
def getRowDelay(self) -> float:
|
||||
return self._row_delay
|
||||
|
||||
def setDirection(self, direction: int):
|
||||
self._direction = direction
|
||||
|
||||
def getDirection(self) -> int:
|
||||
return self._direction
|
||||
|
||||
def setColumns(self, columns: int):
|
||||
self._columns = columns
|
||||
|
||||
def getColumns(self) -> int:
|
||||
return self._columns
|
||||
|
||||
def setRows(self, rows: int):
|
||||
self._rows = rows
|
||||
|
||||
def getRows(self) -> int:
|
||||
return self._rows
|
||||
|
||||
def getDelayForView(self, view: Any) -> int:
|
||||
duration = 0
|
||||
if self._animation:
|
||||
duration = self._animation.getDuration()
|
||||
return int(duration * self._column_delay)
|
||||
|
||||
def willOverlap(self) -> bool:
|
||||
return self._column_delay < 1.0 or self._row_delay < 1.0
|
||||
|
||||
def getAnimationForView(self, view: Any) -> Optional[Animation]:
|
||||
return self._animation
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
# __all__
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
__all__ = [
|
||||
"Animation",
|
||||
"AnimationSet",
|
||||
"AlphaAnimation",
|
||||
"ScaleAnimation",
|
||||
"TranslateAnimation",
|
||||
"RotateAnimation",
|
||||
"AnimationUtils",
|
||||
"Interpolator",
|
||||
"AccelerateInterpolator",
|
||||
"DecelerateInterpolator",
|
||||
"AccelerateDecelerateInterpolator",
|
||||
"LinearInterpolator",
|
||||
"OvershootInterpolator",
|
||||
"AnticipateInterpolator",
|
||||
"AnticipateOvershootInterpolator",
|
||||
"BounceInterpolator",
|
||||
"CycleInterpolator",
|
||||
"PathInterpolator",
|
||||
"Transformation",
|
||||
"LayoutAnimationController",
|
||||
"GridLayoutAnimationController",
|
||||
]
|
||||
Reference in new issue
Block a user