""" Android Transition 组件 — Transition, TransitionManager, Scene, Fade, Slide, Explode 等 方法签名完全对齐 Android SDK (android.transition 包) """ import time from typing import Any, Callable, Dict, List, Optional, Set, Tuple from .._core import Stub, AndroidOnlyError # ═══════════════════════════════════════════════════════════════ # Scene # ═══════════════════════════════════════════════════════════════ class Scene(Stub): """Scene — 转场场景""" def __init__(self, root: Any = None, layout: Any = None): super().__init__() self._root = root self._layout = layout self._entered = False @staticmethod def getSceneForLayout(root: Any, layout_id: int, context: Any) -> "Scene": """从布局资源创建场景""" return Scene(root, layout_id) def getRoot(self) -> Any: return self._root def enter(self): """进入场景""" self._entered = True def exit(self): """退出场景""" self._entered = False def isEntered(self) -> bool: return self._entered def setEnterAction(self, action: Callable): """设置进入动作""" self._enter_action = action def setExitAction(self, action: Callable): """设置退出动作""" self._exit_action = action def toString(self) -> str: return f"Scene(root={self._root}, entered={self._entered})" def hashCode(self) -> int: return hash(id(self._root)) & 0x7FFFFFFF def equals(self, other) -> bool: if not isinstance(other, Scene): return False return self._root is other._root # ═══════════════════════════════════════════════════════════════ # Transition # ═══════════════════════════════════════════════════════════════ class Transition(Stub): """Transition — 转场动画基类""" # 匹配模式 MATCH_VIEW_NAME = 0 MATCH_ID = 1 MATCH_INSTANCE = 2 MATCH_ITEM_ID = 3 def __init__(self): super().__init__() self._duration: int = 300 self._start_delay: int = 0 self._interpolator: Optional[Any] = None self._targets: Set[Any] = set() self._target_ids: Set[int] = set() self._target_names: Set[str] = set() self._target_types: Set[type] = set() self._exclude_targets: Set[Any] = set() self._exclude_ids: Set[int] = set() self._exclude_names: Set[str] = set() self._exclude_types: Set[type] = set() self._listeners: List[Any] = [] self._name: str = "" self._epicenter_callback: Optional[Callable] = None self._path_motion: Optional[Any] = None self._propagation: Optional[Any] = None self._paused: bool = False self._started: bool = False self._ended: bool = False def setDuration(self, duration_ms: int) -> "Transition": """设置持续时间 (毫秒)""" self._duration = max(0, duration_ms) return self def getDuration(self) -> int: return self._duration def setStartDelay(self, start_delay: int) -> "Transition": """设置起始延迟 (毫秒)""" self._start_delay = max(0, start_delay) return self def getStartDelay(self) -> int: return self._start_delay def setInterpolator(self, interpolator: Any) -> "Transition": """设置插值器""" self._interpolator = interpolator return self def getInterpolator(self) -> Any: return self._interpolator def addTarget(self, target: Any) -> "Transition": """添加动画目标""" if isinstance(target, int): self._target_ids.add(target) elif isinstance(target, str): self._target_names.add(target) elif isinstance(target, type): self._target_types.add(target) else: self._targets.add(target) return self def removeTarget(self, target: Any) -> "Transition": """移除动画目标""" if isinstance(target, int): self._target_ids.discard(target) elif isinstance(target, str): self._target_names.discard(target) elif isinstance(target, type): self._target_types.discard(target) else: self._targets.discard(target) return self def getTargets(self) -> List[Any]: return list(self._targets) def excludeTarget(self, target: Any, exclude: bool = True) -> "Transition": """排除目标""" if exclude: if isinstance(target, int): self._exclude_ids.add(target) elif isinstance(target, str): self._exclude_names.add(target) elif isinstance(target, type): self._exclude_types.add(target) else: self._exclude_targets.add(target) else: if isinstance(target, int): self._exclude_ids.discard(target) elif isinstance(target, str): self._exclude_names.discard(target) elif isinstance(target, type): self._exclude_types.discard(target) else: self._exclude_targets.discard(target) return self def addListener(self, listener: Any) -> "Transition": """添加转场监听器""" if listener not in self._listeners: self._listeners.append(listener) return self def removeListener(self, listener: Any) -> "Transition": """移除转场监听器""" if listener in self._listeners: self._listeners.remove(listener) return self def getListeners(self) -> List[Any]: return list(self._listeners) def setName(self, name: str) -> "Transition": self._name = name return self def getName(self) -> str: return self._name def setEpicenterCallback(self, callback: Callable) -> "Transition": self._epicenter_callback = callback return self def getEpicenterCallback(self) -> Optional[Callable]: return self._epicenter_callback def setPathMotion(self, path_motion: Any) -> "Transition": self._path_motion = path_motion return self def getPathMotion(self) -> Any: return self._path_motion def setPropagation(self, propagation: Any) -> "Transition": self._propagation = propagation return self def getPropagation(self) -> Any: return self._propagation def isPaused(self) -> bool: return self._paused def pause(self): """暂停转场""" self._paused = True def resume(self): """恢复转场""" self._paused = False def cancel(self): """取消转场""" self._started = False self._ended = True def end(self): """结束转场""" self._ended = True def toString(self) -> str: return (f"{self.__class__.__name__}(duration={self._duration}, " f"startDelay={self._start_delay}, targets={len(self._targets)})") def hashCode(self) -> int: return id(self) & 0x7FFFFFFF def equals(self, other) -> bool: return self is other def captureStartValues(self, view: Any): """捕获视图起始值""" pass def captureEndValues(self, view: Any): """捕获视图结束值""" pass def createAnimator(self, view: Any, start_values: Any, end_values: Any) -> Optional[Any]: """创建动画器""" return None # ═══════════════════════════════════════════════════════════════ # TransitionSet # ═══════════════════════════════════════════════════════════════ class TransitionSet(Transition): """TransitionSet — 转场合集""" ORDERING_TOGETHER = 0 ORDERING_SEQUENTIAL = 1 def __init__(self): super().__init__() self._ordering = TransitionSet.ORDERING_TOGETHER self._transitions: List[Transition] = [] def setOrdering(self, ordering: int) -> "TransitionSet": """设置播放顺序""" self._ordering = ordering return self def getOrdering(self) -> int: return self._ordering def addTransition(self, transition: Transition) -> "TransitionSet": """添加子转场""" self._transitions.append(transition) return self def removeTransition(self, transition: Transition) -> "TransitionSet": """移除子转场""" if transition in self._transitions: self._transitions.remove(transition) return self def getTransitionAt(self, index: int) -> Optional[Transition]: """获取指定索引的子转场""" if 0 <= index < len(self._transitions): return self._transitions[index] return None def getTransitionCount(self) -> int: return len(self._transitions) def toString(self) -> str: return (f"TransitionSet(ordering={self._ordering}, " f"count={len(self._transitions)})") # ═══════════════════════════════════════════════════════════════ # AutoTransition # ═══════════════════════════════════════════════════════════════ class AutoTransition(TransitionSet): """AutoTransition — 自动过渡转场""" def __init__(self): super().__init__() self.setOrdering(TransitionSet.ORDERING_TOGETHER) self._duration = 300 def toString(self) -> str: return f"AutoTransition(duration={self._duration})" # ═══════════════════════════════════════════════════════════════ # Fade # ═══════════════════════════════════════════════════════════════ class Fade(Transition): """Fade — 淡入淡出转场""" IN = 0x00000001 OUT = 0x00000002 def __init__(self, fading_mode: int = IN | OUT): super().__init__() self._fading_mode = fading_mode def getFadingMode(self) -> int: return self._fading_mode def setFadingMode(self, fading_mode: int): self._fading_mode = fading_mode def toString(self) -> str: return f"Fade(mode={self._fading_mode}, duration={self._duration})" # ═══════════════════════════════════════════════════════════════ # ChangeBounds # ═══════════════════════════════════════════════════════════════ class ChangeBounds(Transition): """ChangeBounds — 位置变化转场""" def __init__(self): super().__init__() self._resize_clip: bool = False self._reparent: bool = False self._reparent_with_overlay: bool = True def setResizeClip(self, resize_clip: bool): self._resize_clip = resize_clip def getResizeClip(self) -> bool: return self._resize_clip def setReparent(self, reparent: bool): self._reparent = reparent def getReparent(self) -> bool: return self._reparent def setReparentWithOverlay(self, reparent_with_overlay: bool): self._reparent_with_overlay = reparent_with_overlay def getReparentWithOverlay(self) -> bool: return self._reparent_with_overlay def toString(self) -> str: return f"ChangeBounds(duration={self._duration}, resizeClip={self._resize_clip})" # ═══════════════════════════════════════════════════════════════ # ChangeTransform # ═══════════════════════════════════════════════════════════════ class ChangeTransform(Transition): """ChangeTransform — 变换属性转场""" def __init__(self): super().__init__() self._reparent: bool = False self._reparent_with_overlay: bool = True def setReparent(self, reparent: bool): self._reparent = reparent def getReparent(self) -> bool: return self._reparent def setReparentWithOverlay(self, reparent_with_overlay: bool): self._reparent_with_overlay = reparent_with_overlay def getReparentWithOverlay(self) -> bool: return self._reparent_with_overlay def toString(self) -> str: return f"ChangeTransform(duration={self._duration})" # ═══════════════════════════════════════════════════════════════ # Slide # ═══════════════════════════════════════════════════════════════ class Slide(Transition): """Slide — 滑动转场""" TOP = 0x00000001 BOTTOM = 0x00000002 START = 0x00000003 END = 0x00000004 RIGHT = 0x00000005 LEFT = 0x00000006 def __init__(self, slide_edge: int = BOTTOM): super().__init__() self._slide_edge = slide_edge def getSlideEdge(self) -> int: return self._slide_edge def setSlideEdge(self, slide_edge: int): self._slide_edge = slide_edge def toString(self) -> str: return f"Slide(edge={self._slide_edge}, duration={self._duration})" # ═══════════════════════════════════════════════════════════════ # Explode # ═══════════════════════════════════════════════════════════════ class Explode(Transition): """Explode — 爆炸/散开转场""" def __init__(self): super().__init__() def toString(self) -> str: return f"Explode(duration={self._duration})" # ═══════════════════════════════════════════════════════════════ # TransitionManager # ═══════════════════════════════════════════════════════════════ class TransitionManager(Stub): """TransitionManager — 转场管理器""" def __init__(self): super().__init__() @staticmethod def beginDelayedTransition(scene_root: Any, transition: Optional[Transition] = None): """开始延迟转场""" pass @staticmethod def endTransitions(scene_root: Any): """结束转场""" pass @staticmethod def go(scene: Scene, transition: Optional[Transition] = None): """执行场景转场""" if scene: scene.enter() def toString(self) -> str: return "TransitionManager(desktop-stub)" def hashCode(self) -> int: return hash("android.transition.TransitionManager") & 0x7FFFFFFF def equals(self, other) -> bool: return isinstance(other, TransitionManager) # ═══════════════════════════════════════════════════════════════ # __all__ # ═══════════════════════════════════════════════════════════════ __all__ = [ "Transition", "TransitionManager", "AutoTransition", "Fade", "ChangeBounds", "ChangeTransform", "Slide", "Explode", "TransitionSet", "Scene", ]