""" Android ActionBar API — ActionBar, ActionBar.Tab, ActionBar.TabListener, ActionBar.LayoutParams 方法签名完全对齐 Android SDK """ from __future__ import annotations from typing import Any, Dict, List, Optional, Tuple, Callable from .._core import Stub, AndroidOnlyError from ..java.lang import RuntimeException IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) # ═══════════════════════════════════════════════════════════════ # 常量 # ═══════════════════════════════════════════════════════════════ # DISPLAY_* 常量 DISPLAY_USE_LOGO = 0x0001 DISPLAY_SHOW_HOME = 0x0002 DISPLAY_HOME_AS_UP = 0x0004 DISPLAY_SHOW_TITLE = 0x0008 DISPLAY_SHOW_CUSTOM = 0x0010 DISPLAY_TITLE_MULTIPLE_LINES = 0x0020 # NAVIGATION_MODE_* 常量 NAVIGATION_MODE_STANDARD = 0 NAVIGATION_MODE_LIST = 1 NAVIGATION_MODE_TABS = 2 # TAB 状态常量 TAB_STATE_CREATED = 1 TAB_STATE_INITIALIZED = 2 TAB_STATE_SELECTED = 3 TAB_STATE_UNSELECTED = 4 TAB_STATE_RESELECTED = 5 # 其它常量 SHOW_AS_ACTION_NEVER = 0 SHOW_AS_ACTION_IF_ROOM = 1 SHOW_AS_ACTION_ALWAYS = 2 SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW = 8 SHOW_AS_ACTION_WITH_TEXT = 4 # ═══════════════════════════════════════════════════════════════ # ActionBar # ═══════════════════════════════════════════════════════════════ class ActionBar(Stub): """ActionBar — 操作栏 (桌面存根)""" DISPLAY_USE_LOGO = DISPLAY_USE_LOGO DISPLAY_SHOW_HOME = DISPLAY_SHOW_HOME DISPLAY_HOME_AS_UP = DISPLAY_HOME_AS_UP DISPLAY_SHOW_TITLE = DISPLAY_SHOW_TITLE DISPLAY_SHOW_CUSTOM = DISPLAY_SHOW_CUSTOM DISPLAY_HOME_AS_UP_FLAG = DISPLAY_HOME_AS_UP DISPLAY_TITLE_MULTIPLE_LINES = DISPLAY_TITLE_MULTIPLE_LINES NAVIGATION_MODE_STANDARD = NAVIGATION_MODE_STANDARD NAVIGATION_MODE_LIST = NAVIGATION_MODE_LIST NAVIGATION_MODE_TABS = NAVIGATION_MODE_TABS def __init__(self): super().__init__() self._mTitle: Optional[str] = None self._mSubtitle: Optional[str] = None self._mLogo: Optional[Any] = None self._mIcon: Optional[Any] = None self._mCustomView: Optional[Any] = None self._mDisplayOptions = DISPLAY_SHOW_HOME | DISPLAY_SHOW_TITLE self._mNavigationMode = NAVIGATION_MODE_STANDARD self._mSelectedNavigationIndex = 0 self._mListNavigationCallbacks: Optional[Callable] = None self._mTabs: List["ActionBar.Tab"] = [] self._mSelectedTab: Optional["ActionBar.Tab"] = None self._mHomeButtonEnabled = True self._mShowing = True self._mElevation = 0.0 self._mHideOffset = 0 self._mHideOnContentScroll = False self._mBackgroundDrawable: Optional[Any] = None self._mStackedBackgroundDrawable: Optional[Any] = None self._mSplitBackgroundDrawable: Optional[Any] = None self._mCustomViewLayoutParams: Optional["ActionBar.LayoutParams"] = None self._mContext: Optional[Any] = None self._mThemedContext: Optional[Any] = None self._mMenuVisibilityListeners: List[Callable] = [] self._mMenuVisible = True self._mShowHideAnimationEnabled = False self._mShowHideAnimationListener: Optional[Any] = None self._mActionMode: Optional[Any] = None self._mActionModeListener: Optional[Any] = None self._mTabListener: Optional["ActionBar.TabListener"] = None def setTitle(self, title: str) -> None: self._mTitle = title def setTitle(self, titleResId: int) -> None: self._mTitle = f"title_{titleResId}" def getTitle(self) -> Optional[str]: return self._mTitle def setSubtitle(self, subtitle: str) -> None: self._mSubtitle = subtitle def setSubtitle(self, subtitleResId: int) -> None: self._mSubtitle = f"subtitle_{subtitleResId}" def getSubtitle(self) -> Optional[str]: return self._mSubtitle def setLogo(self, logo: Any) -> None: self._mLogo = logo def setIcon(self, icon: Any) -> None: self._mIcon = icon def setIcon(self, iconResId: int) -> None: pass def setLogo(self, logoResId: int) -> None: pass def setHomeButtonEnabled(self, enabled: bool) -> None: self._mHomeButtonEnabled = enabled def isHomeButtonEnabled(self) -> bool: return self._mHomeButtonEnabled def setDisplayOptions(self, options: int) -> None: self._mDisplayOptions = options def setDisplayOptions(self, options: int, mask: int) -> None: self._mDisplayOptions = (self._mDisplayOptions & ~mask) | (options & mask) def getDisplayOptions(self) -> int: return self._mDisplayOptions def setNavigationMode(self, mode: int) -> None: self._mNavigationMode = mode def getNavigationMode(self) -> int: return self._mNavigationMode def setSelectedNavigationItem(self, position: int) -> None: self._mSelectedNavigationIndex = position if self._mNavigationMode == NAVIGATION_MODE_TABS: if 0 <= position < len(self._mTabs): self._mSelectedTab = self._mTabs[position] def getSelectedNavigationIndex(self) -> int: if self._mNavigationMode == NAVIGATION_MODE_TABS and self._mSelectedTab: try: return self._mTabs.index(self._mSelectedTab) except ValueError: pass return self._mSelectedNavigationIndex def setListNavigationCallbacks(self, adapter: Any, callback: Any) -> None: self._mListNavigationCallbacks = callback def getListNavigationCallbacks(self) -> Optional[Any]: return self._mListNavigationCallbacks def getSelectedTab(self) -> Optional["ActionBar.Tab"]: return self._mSelectedTab def addTab(self, tab: "ActionBar.Tab") -> None: self._mTabs.append(tab) if len(self._mTabs) == 1: self._mSelectedTab = tab def addTab(self, tab: "ActionBar.Tab", setSelected: bool) -> None: self._mTabs.append(tab) if setSelected: self._mSelectedTab = tab def addTab(self, tab: "ActionBar.Tab", position: int, setSelected: bool) -> None: if position < 0: position = 0 if position > len(self._mTabs): position = len(self._mTabs) self._mTabs.insert(position, tab) if setSelected: self._mSelectedTab = tab def removeTab(self, tab: "ActionBar.Tab") -> None: if tab in self._mTabs: self._mTabs.remove(tab) if self._mSelectedTab is tab: self._mSelectedTab = self._mTabs[0] if self._mTabs else None def removeTabAt(self, position: int) -> None: if 0 <= position < len(self._mTabs): tab = self._mTabs[position] self._mTabs.pop(position) if self._mSelectedTab is tab: self._mSelectedTab = self._mTabs[0] if self._mTabs else None def removeAllTabs(self) -> None: self._mTabs.clear() self._mSelectedTab = None def selectTab(self, tab: "ActionBar.Tab") -> None: if tab in self._mTabs: old = self._mSelectedTab self._mSelectedTab = tab if old and old._mListener: old._mListener.onTabUnselected(old, None) if tab._mListener: tab._mListener.onTabSelected(tab, None) def getTabCount(self) -> int: return len(self._mTabs) def getTabAt(self, index: int) -> Optional["ActionBar.Tab"]: if 0 <= index < len(self._mTabs): return self._mTabs[index] return None def newTab(self) -> "ActionBar.Tab": return ActionBar.Tab() def setCustomView(self, view: Any) -> None: self._mCustomView = view def setCustomView(self, view: Any, layoutParams: "ActionBar.LayoutParams") -> None: self._mCustomView = view self._mCustomViewLayoutParams = layoutParams def setCustomView(self, layoutResId: int) -> None: pass def getCustomView(self) -> Optional[Any]: return self._mCustomView def setBackgroundDrawable(self, drawable: Any) -> None: self._mBackgroundDrawable = drawable def setStackedBackgroundDrawable(self, drawable: Any) -> None: self._mStackedBackgroundDrawable = drawable def setSplitBackgroundDrawable(self, drawable: Any) -> None: self._mSplitBackgroundDrawable = drawable def show(self) -> None: self._mShowing = True def hide(self) -> None: self._mShowing = False def isShowing(self) -> bool: return self._mShowing def setShowHideAnimationEnabled(self, enabled: bool) -> None: self._mShowHideAnimationEnabled = enabled def getThemedContext(self) -> Optional[Any]: return self._mThemedContext or self._mContext def setHomeAsUpIndicator(self, indicator: Any) -> None: pass def setHomeAsUpIndicator(self, indicatorResId: int) -> None: pass def setHomeActionContentDescription(self, description: str) -> None: pass def setHomeActionContentDescription(self, resId: int) -> None: pass def setElevation(self, elevation: float) -> None: self._mElevation = elevation def getElevation(self) -> float: return self._mElevation def setHideOffset(self, offset: int) -> None: self._mHideOffset = offset def getHideOffset(self) -> int: return self._mHideOffset def setHideOnContentScrollEnabled(self, hideOnContentScroll: bool) -> None: self._mHideOnContentScroll = hideOnContentScroll def isHideOnContentScrollEnabled(self) -> bool: return self._mHideOnContentScroll def getContext(self) -> Optional[Any]: return self._mContext def addOnMenuVisibilityListener(self, listener: Callable) -> None: if listener not in self._mMenuVisibilityListeners: self._mMenuVisibilityListeners.append(listener) def removeOnMenuVisibilityListener(self, listener: Callable) -> None: if listener in self._mMenuVisibilityListeners: self._mMenuVisibilityListeners.remove(listener) def dispatchMenuVisibilityChanged(self, isVisible: bool) -> None: self._mMenuVisible = isVisible for listener in self._mMenuVisibilityListeners: listener(isVisible) def startActionMode(self, callback: Any) -> Optional[Any]: self._mActionMode = callback return None def invalidateOptionsMenu(self) -> None: pass def onConfigurationChanged(self, config: Any) -> None: pass def onDestroy(self) -> None: self._mTabs.clear() self._mSelectedTab = None def toString(self) -> str: return ( f"ActionBar(title={self._mTitle}, subtitle={self._mSubtitle}, " f"tabs={len(self._mTabs)}, display=0x{self._mDisplayOptions:x}, " f"showing={self._mShowing})" ) # ═══════════════════════════════════════════════════════════ # ActionBar.Tab # ═══════════════════════════════════════════════════════════ class Tab(Stub): """ActionBar.Tab — 操作栏标签""" INVALID_POSITION = -1 def __init__(self): super().__init__() self._mListener: Optional["ActionBar.TabListener"] = None self._mObjectTag: Optional[Any] = None self._mPosition = Tab.INVALID_POSITION self._mIcon: Optional[Any] = None self._mText: Optional[str] = None self._mContentDescription: Optional[str] = None self._mCustomView: Optional[Any] = None self._mParentActionBar: Optional["ActionBar"] = None self._mIconResId = 0 def getPosition(self) -> int: return self._mPosition def getIcon(self) -> Optional[Any]: return self._mIcon def getText(self) -> Optional[str]: return self._mText def setIcon(self, icon: Any) -> "ActionBar.Tab": self._mIcon = icon return self def setIcon(self, iconResId: int) -> "ActionBar.Tab": self._mIconResId = iconResId return self def setText(self, text: str) -> "ActionBar.Tab": self._mText = text return self def setText(self, textResId: int) -> "ActionBar.Tab": self._mText = f"tab_text_{textResId}" return self def setCustomView(self, view: Any) -> "ActionBar.Tab": self._mCustomView = view return self def setCustomView(self, layoutResId: int) -> "ActionBar.Tab": return self def getCustomView(self) -> Optional[Any]: return self._mCustomView def setTag(self, tag: Any) -> "ActionBar.Tab": self._mObjectTag = tag return self def getTag(self) -> Optional[Any]: return self._mObjectTag def setTabListener(self, listener: "ActionBar.TabListener") -> "ActionBar.Tab": self._mListener = listener return self def getTabListener(self) -> Optional["ActionBar.TabListener"]: return self._mListener def setContentDescription(self, description: str) -> "ActionBar.Tab": self._mContentDescription = description return self def getContentDescription(self) -> Optional[str]: return self._mContentDescription def select(self) -> None: if self._mParentActionBar: self._mParentActionBar.selectTab(self) def isSelected(self) -> bool: if self._mParentActionBar: return self._mParentActionBar.getSelectedTab() is self return False def toString(self) -> str: return f"ActionBar.Tab(text={self._mText}, position={self._mPosition})" # ═══════════════════════════════════════════════════════════ # ActionBar.TabListener # ═══════════════════════════════════════════════════════════ class TabListener(Stub): """ActionBar.TabListener — 标签事件监听器""" def __init__(self): super().__init__() def onTabSelected(self, tab: "ActionBar.Tab", ft: Any) -> None: pass def onTabUnselected(self, tab: "ActionBar.Tab", ft: Any) -> None: pass def onTabReselected(self, tab: "ActionBar.Tab", ft: Any) -> None: pass def toString(self) -> str: return "ActionBar.TabListener" # ═══════════════════════════════════════════════════════════ # ActionBar.LayoutParams # ═══════════════════════════════════════════════════════════ class LayoutParams(Stub): """ActionBar.LayoutParams — 操作栏布局参数""" # 对齐方式 GRAVITY_LEFT = 0x03 GRAVITY_CENTER_HORIZONTAL = 0x01 GRAVITY_RIGHT = 0x05 GRAVITY_TOP = 0x30 GRAVITY_CENTER_VERTICAL = 0x10 GRAVITY_BOTTOM = 0x50 GRAVITY_CENTER = 0x11 def __init__(self, context: Any = None): super().__init__() self._gravity = LayoutParams.GRAVITY_CENTER_VERTICAL self._width = -1 # MATCH_PARENT self._height = -2 # WRAP_CONTENT self._margin_left = 0 self._margin_top = 0 self._margin_right = 0 self._margin_bottom = 0 def __init__(self, gravity: int): super().__init__() self._gravity = gravity self._width = -1 self._height = -1 def __init__(self, width: int, height: int): super().__init__() self._width = width self._height = height self._gravity = LayoutParams.GRAVITY_CENTER_VERTICAL def __init__(self, width: int, height: int, gravity: int): super().__init__() self._width = width self._height = height self._gravity = gravity def getGravity(self) -> int: return self._gravity def setGravity(self, gravity: int) -> None: self._gravity = gravity def getWidth(self) -> int: return self._width def setWidth(self, width: int) -> None: self._width = width def getHeight(self) -> int: return self._height def setHeight(self, height: int) -> None: self._height = height def getMargins(self) -> Tuple[int, int, int, int]: return (self._margin_left, self._margin_top, self._margin_right, self._margin_bottom) def setMargins(self, left: int, top: int, right: int, bottom: int) -> None: self._margin_left = left self._margin_top = top self._margin_right = right self._margin_bottom = bottom def toString(self) -> str: return f"ActionBar.LayoutParams(width={self._width}, height={self._height}, gravity=0x{self._gravity:x})" # 兼容多个 __init__ 签名 def __init__(self, *args, **kwargs): super().__init__() self._gravity = LayoutParams.GRAVITY_CENTER_VERTICAL self._width = -1 self._height = -1 self._margin_left = 0 self._margin_top = 0 self._margin_right = 0 self._margin_bottom = 0 if len(args) == 1: if isinstance(args[0], int): self._gravity = args[0] elif isinstance(args[0], ActionBar.LayoutParams): other = args[0] self._width = other._width self._height = other._height self._gravity = other._gravity elif len(args) == 2: self._width, self._height = args elif len(args) == 3: self._width, self._height, self._gravity = args