- 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关键字冲突
874 lines
31 KiB
Python
874 lines
31 KiB
Python
"""
|
|
Android Dialog API — Dialog, AlertDialog, DatePickerDialog, TimePickerDialog, ProgressDialog, etc.
|
|
方法签名完全对齐 Android SDK
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import time
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Optional, Set, Tuple, Callable
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
from ..java.lang import RuntimeException
|
|
|
|
IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {})
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# 常量
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
# BUTTON_* 常量
|
|
BUTTON_POSITIVE = -1
|
|
BUTTON_NEGATIVE = -2
|
|
BUTTON_NEUTRAL = -3
|
|
|
|
# THEME_* 常量
|
|
THEME_TRADITIONAL = 0
|
|
THEME_DEVICE_DEFAULT_DARK = 1
|
|
THEME_DEVICE_DEFAULT_LIGHT = 2
|
|
THEME_HOLO_DARK = 3
|
|
THEME_HOLO_LIGHT = 4
|
|
THEME_MATERIAL_DARK = 5
|
|
THEME_MATERIAL_LIGHT = 6
|
|
|
|
# Dialog 常量
|
|
DISMISS_OTHER = 0
|
|
DISMISS_BUTTON_POSITIVE = 1
|
|
DISMISS_BUTTON_NEGATIVE = 2
|
|
DISMISS_BUTTON_NEUTRAL = 3
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DialogInterface
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DialogInterface(Stub):
|
|
"""DialogInterface — 对话框接口"""
|
|
|
|
BUTTON_POSITIVE = BUTTON_POSITIVE
|
|
BUTTON_NEGATIVE = BUTTON_NEGATIVE
|
|
BUTTON_NEUTRAL = BUTTON_NEUTRAL
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def cancel(self) -> None:
|
|
pass
|
|
|
|
def dismiss(self) -> None:
|
|
pass
|
|
|
|
class OnClickListener(Stub):
|
|
"""DialogInterface.OnClickListener — 点击监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onClick(self, dialog: Any, which: int) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnClickListener"
|
|
|
|
class OnDismissListener(Stub):
|
|
"""DialogInterface.OnDismissListener — 消除监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onDismiss(self, dialog: Any) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnDismissListener"
|
|
|
|
class OnCancelListener(Stub):
|
|
"""DialogInterface.OnCancelListener — 取消监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onCancel(self, dialog: Any) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnCancelListener"
|
|
|
|
class OnMultiChoiceClickListener(Stub):
|
|
"""DialogInterface.OnMultiChoiceClickListener — 多选点击监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onClick(self, dialog: Any, which: int, isChecked: bool) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnMultiChoiceClickListener"
|
|
|
|
class OnShowListener(Stub):
|
|
"""DialogInterface.OnShowListener — 显示监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onShow(self, dialog: Any) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnShowListener"
|
|
|
|
class OnKeyListener(Stub):
|
|
"""DialogInterface.OnKeyListener — 按键监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onKey(self, dialog: Any, keyCode: int, event: Any) -> bool:
|
|
return False
|
|
|
|
def toString(self) -> str:
|
|
return "OnKeyListener"
|
|
|
|
def toString(self) -> str:
|
|
return "DialogInterface"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# Dialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class Dialog(DialogInterface):
|
|
"""Dialog — 对话框基类 (桌面存根)"""
|
|
|
|
def __init__(self, context: Any = None, themeResId: int = 0):
|
|
super().__init__()
|
|
self._context = context
|
|
self._theme_res_id = themeResId
|
|
self._mShowing = False
|
|
self._mCancelable = True
|
|
self._mCanceled = False
|
|
self._mCancelMessage: Optional[Any] = None
|
|
self._mDismissMessage: Optional[Any] = None
|
|
self._mShowMessage: Optional[Any] = None
|
|
self._mWindow: Optional[Any] = None
|
|
self._mOwnerActivity: Optional[Any] = None
|
|
self._mOnCancelListener: Optional[DialogInterface.OnCancelListener] = None
|
|
self._mOnDismissListener: Optional[DialogInterface.OnDismissListener] = None
|
|
self._mOnShowListener: Optional[DialogInterface.OnShowListener] = None
|
|
self._mOnKeyListener: Optional[DialogInterface.OnKeyListener] = None
|
|
self._mCancelListeners: List[DialogInterface.OnCancelListener] = []
|
|
self._mDismissListeners: List[DialogInterface.OnDismissListener] = []
|
|
self._mShowListeners: List[DialogInterface.OnShowListener] = []
|
|
self._mCreated = False
|
|
self._mDecor: Optional[Any] = None
|
|
self._mActionMode: Optional[Any] = None
|
|
self._mActionModeType: Optional[Any] = None
|
|
self._mDismissRunnable: Optional[Any] = None
|
|
|
|
def show(self) -> None:
|
|
self._mShowing = True
|
|
if self._mOnShowListener:
|
|
self._mOnShowListener.onShow(self)
|
|
for listener in self._mShowListeners:
|
|
listener.onShow(self)
|
|
|
|
def hide(self) -> None:
|
|
self._mShowing = False
|
|
|
|
def dismiss(self) -> None:
|
|
self._mShowing = False
|
|
if self._mOnDismissListener:
|
|
self._mOnDismissListener.onDismiss(self)
|
|
for listener in self._mDismissListeners:
|
|
listener.onDismiss(self)
|
|
|
|
def cancel(self) -> None:
|
|
if not self._mCancelable:
|
|
return
|
|
self._mCanceled = True
|
|
if self._mOnCancelListener:
|
|
self._mOnCancelListener.onCancel(self)
|
|
for listener in self._mCancelListeners:
|
|
listener.onCancel(self)
|
|
self.dismiss()
|
|
|
|
def isShowing(self) -> bool:
|
|
return self._mShowing
|
|
|
|
def setCancelable(self, flag: bool) -> None:
|
|
self._mCancelable = flag
|
|
|
|
def setCanceledOnTouchOutside(self, cancel: bool) -> None:
|
|
pass
|
|
|
|
def isCancelable(self) -> bool:
|
|
return self._mCancelable
|
|
|
|
def getContext(self) -> Optional[Any]:
|
|
return self._context
|
|
|
|
def getWindow(self) -> Optional[Any]:
|
|
return self._mWindow
|
|
|
|
def getOwnerActivity(self) -> Optional[Any]:
|
|
return self._mOwnerActivity
|
|
|
|
def setOwnerActivity(self, activity: Any) -> None:
|
|
self._mOwnerActivity = activity
|
|
|
|
def setOnCancelListener(self, listener: Optional[DialogInterface.OnCancelListener]) -> None:
|
|
self._mOnCancelListener = listener
|
|
|
|
def setOnDismissListener(self, listener: Optional[DialogInterface.OnDismissListener]) -> None:
|
|
self._mOnDismissListener = listener
|
|
|
|
def setOnShowListener(self, listener: Optional[DialogInterface.OnShowListener]) -> None:
|
|
self._mOnShowListener = listener
|
|
|
|
def setOnKeyListener(self, listener: Optional[DialogInterface.OnKeyListener]) -> None:
|
|
self._mOnKeyListener = listener
|
|
|
|
def setCancelMessage(self, msg: Any) -> None:
|
|
self._mCancelMessage = msg
|
|
|
|
def setDismissMessage(self, msg: Any) -> None:
|
|
self._mDismissMessage = msg
|
|
|
|
def setTitle(self, title: str) -> None:
|
|
pass
|
|
|
|
def setVolumeControlStream(self, streamType: int) -> None:
|
|
pass
|
|
|
|
def getVolumeControlStream(self) -> int:
|
|
return -1
|
|
|
|
def onWindowFocusChanged(self, hasFocus: bool) -> None:
|
|
pass
|
|
|
|
def onBackPressed(self) -> None:
|
|
self.cancel()
|
|
|
|
def onAttachedToWindow(self) -> None:
|
|
pass
|
|
|
|
def onDetachedFromWindow(self) -> None:
|
|
pass
|
|
|
|
def onContentChanged(self) -> None:
|
|
pass
|
|
|
|
def onWindowAttributesChanged(self, attrs: Any) -> None:
|
|
pass
|
|
|
|
def stopManagingActionMode(self, actionMode: Any) -> None:
|
|
pass
|
|
|
|
def startManagingActionMode(self, actionMode: Any) -> None:
|
|
pass
|
|
|
|
def takeActionMode(self, actionMode: Any) -> None:
|
|
pass
|
|
|
|
def onActionModeStarted(self, actionMode: Any) -> None:
|
|
pass
|
|
|
|
def onActionModeFinished(self, actionMode: Any) -> None:
|
|
pass
|
|
|
|
def addContentView(self, view: Any, params: Any) -> None:
|
|
pass
|
|
|
|
def setContentView(self, viewOrRes: Any, params: Any = None) -> None:
|
|
pass
|
|
|
|
def requireViewById(self, id: int) -> Any:
|
|
return None
|
|
|
|
def requireViewById(self, id: int) -> Any:
|
|
result = self.findViewById(id)
|
|
if result is None:
|
|
raise IllegalArgumentException(f"View id=0x{id:x} not found")
|
|
return result
|
|
|
|
def requestWindowFeature(self, featureId: int) -> bool:
|
|
return True
|
|
|
|
def getLayoutInflater(self) -> Any:
|
|
return None
|
|
|
|
def onRestoreInstanceState(self, savedInstanceState: Any) -> None:
|
|
pass
|
|
|
|
def onSaveInstanceState(self) -> Any:
|
|
return None
|
|
|
|
def toString(self) -> str:
|
|
return f"Dialog(showing={self._mShowing}, cancelable={self._mCancelable})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# AlertDialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class AlertDialog(Dialog):
|
|
"""AlertDialog — 警示对话框"""
|
|
|
|
THEME_DEVICE_DEFAULT_DARK = THEME_DEVICE_DEFAULT_DARK
|
|
THEME_DEVICE_DEFAULT_LIGHT = THEME_DEVICE_DEFAULT_LIGHT
|
|
THEME_HOLO_DARK = THEME_HOLO_DARK
|
|
THEME_HOLO_LIGHT = THEME_HOLO_LIGHT
|
|
THEME_MATERIAL_DARK = THEME_MATERIAL_DARK
|
|
THEME_MATERIAL_LIGHT = THEME_MATERIAL_LIGHT
|
|
THEME_TRADITIONAL = THEME_TRADITIONAL
|
|
|
|
def __init__(self, context: Any, themeResId: int = 0):
|
|
super().__init__(context, themeResId)
|
|
self._mTitle: Optional[str] = None
|
|
self._mMessage: Optional[str] = None
|
|
self._mIcon: Optional[Any] = None
|
|
self._mIconAttrId = 0
|
|
self._mPositiveButtonText: Optional[str] = None
|
|
self._mNegativeButtonText: Optional[str] = None
|
|
self._mNeutralButtonText: Optional[str] = None
|
|
self._mPositiveButtonListener: Optional[DialogInterface.OnClickListener] = None
|
|
self._mNegativeButtonListener: Optional[DialogInterface.OnClickListener] = None
|
|
self._mNeutralButtonListener: Optional[DialogInterface.OnClickListener] = None
|
|
self._mItems: Optional[List[str]] = None
|
|
self._mItemClickListener: Optional[DialogInterface.OnClickListener] = None
|
|
self._mAdapter: Optional[Any] = None
|
|
self._mMultiChoiceItems: Optional[List[str]] = None
|
|
self._mMultiChoiceListener: Optional[DialogInterface.OnMultiChoiceClickListener] = None
|
|
self._mCheckedItems: Optional[List[bool]] = None
|
|
self._mView: Optional[Any] = None
|
|
self._mViewSpacingLeft = 0
|
|
self._mViewSpacingTop = 0
|
|
self._mViewSpacingRight = 0
|
|
self._mViewSpacingBottom = 0
|
|
self._mViewSpacingSpecified = False
|
|
self._mCancelable = True
|
|
self._mCancelListener: Optional[DialogInterface.OnCancelListener] = None
|
|
self._mDismissListener: Optional[DialogInterface.OnDismissListener] = None
|
|
self._mKeyListener: Optional[DialogInterface.OnKeyListener] = None
|
|
self._mCustomTitleView: Optional[Any] = None
|
|
self._mMessageView: Optional[Any] = None
|
|
self._mScrollView: Optional[Any] = None
|
|
self._mListView: Optional[Any] = None
|
|
self._mButtonPanelLayout: Optional[Any] = None
|
|
self._mAlertDialogLayout = 0
|
|
self._mButtonPanelSideLayout = 0
|
|
self._mListLayout = 0
|
|
self._mMultiChoiceLayout = 0
|
|
self._mSingleChoiceLayout = 0
|
|
self._mProgressLayout = 0
|
|
self._mProgressNumber: Optional[str] = None
|
|
self._mProgressPercent: Optional[str] = None
|
|
self._mProgressStyle = 0
|
|
self._mProgressValue = 0
|
|
self._mProgressValueMax = 100
|
|
self._mProgressIndeterminate = False
|
|
self._mCheckedItem = -1
|
|
self._mForceInverseBackground = False
|
|
self._mRecycleOnMeasure = True
|
|
self._mShowTitle = True
|
|
|
|
def getButton(self, whichButton: int) -> Optional[Any]:
|
|
return None
|
|
|
|
def setTitle(self, title: str) -> None:
|
|
self._mTitle = title
|
|
|
|
def setMessage(self, message: str) -> None:
|
|
self._mMessage = message
|
|
|
|
def setIcon(self, icon: Any) -> None:
|
|
self._mIcon = icon
|
|
|
|
def setIconAttribute(self, attrId: int) -> None:
|
|
self._mIconAttrId = attrId
|
|
|
|
def setCustomTitle(self, customTitleView: Any) -> None:
|
|
self._mCustomTitleView = customTitleView
|
|
|
|
def setView(self, view: Any) -> None:
|
|
self._mView = view
|
|
|
|
def setView(self, view: Any, viewSpacingLeft: int, viewSpacingTop: int, viewSpacingRight: int, viewSpacingBottom: int) -> None:
|
|
self._mView = view
|
|
self._mViewSpacingLeft = viewSpacingLeft
|
|
self._mViewSpacingTop = viewSpacingTop
|
|
self._mViewSpacingRight = viewSpacingRight
|
|
self._mViewSpacingBottom = viewSpacingBottom
|
|
self._mViewSpacingSpecified = True
|
|
|
|
def setButton(self, whichButton: int, text: Any, listenerOrMsg: Any = None) -> None:
|
|
text_str = str(text) if not isinstance(text, str) else text
|
|
if whichButton == BUTTON_POSITIVE:
|
|
self._mPositiveButtonText = text_str
|
|
if isinstance(listenerOrMsg, DialogInterface.OnClickListener):
|
|
self._mPositiveButtonListener = listenerOrMsg
|
|
elif whichButton == BUTTON_NEGATIVE:
|
|
self._mNegativeButtonText = text_str
|
|
if isinstance(listenerOrMsg, DialogInterface.OnClickListener):
|
|
self._mNegativeButtonListener = listenerOrMsg
|
|
elif whichButton == BUTTON_NEUTRAL:
|
|
self._mNeutralButtonText = text_str
|
|
if isinstance(listenerOrMsg, DialogInterface.OnClickListener):
|
|
self._mNeutralButtonListener = listenerOrMsg
|
|
|
|
def setIconAttribute(self, attrId: int) -> None:
|
|
self._mIconAttrId = attrId
|
|
|
|
def getListView(self) -> Optional[Any]:
|
|
return self._mListView
|
|
|
|
def show(self) -> None:
|
|
super().show()
|
|
# 模拟按钮点击触发
|
|
if self._mPositiveButtonListener:
|
|
pass
|
|
if self._mNegativeButtonListener:
|
|
pass
|
|
if self._mNeutralButtonListener:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return f"AlertDialog(title={self._mTitle}, message={self._mMessage})"
|
|
|
|
# ═══════════════════════════════════════════════════════════
|
|
# AlertDialog.Builder
|
|
# ═══════════════════════════════════════════════════════════
|
|
|
|
class Builder(Stub):
|
|
"""AlertDialog.Builder — 警示对话框构建器"""
|
|
|
|
def __init__(self, context: Any):
|
|
super().__init__()
|
|
self._P = AlertDialog(context)
|
|
self._context = context
|
|
|
|
def setTitle(self, titleOrId: Any) -> "AlertDialog.Builder":
|
|
if isinstance(titleOrId, int):
|
|
self._P._mTitle = f"title_{titleOrId}"
|
|
else:
|
|
self._P._mTitle = str(titleOrId)
|
|
return self
|
|
|
|
def setCustomTitle(self, customTitleView: Any) -> "AlertDialog.Builder":
|
|
self._P._mCustomTitleView = customTitleView
|
|
return self
|
|
|
|
def setMessage(self, messageOrId: Any) -> "AlertDialog.Builder":
|
|
if isinstance(messageOrId, int):
|
|
self._P._mMessage = f"msg_{messageOrId}"
|
|
else:
|
|
self._P._mMessage = str(messageOrId)
|
|
return self
|
|
|
|
def setIcon(self, iconOrId: Any) -> "AlertDialog.Builder":
|
|
if isinstance(iconOrId, int):
|
|
pass
|
|
else:
|
|
self._P._mIcon = iconOrId
|
|
return self
|
|
|
|
def setIconAttribute(self, attrId: int) -> "AlertDialog.Builder":
|
|
self._P._mIconAttrId = attrId
|
|
return self
|
|
|
|
def setPositiveButton(
|
|
self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(textOrId, int):
|
|
self._P._mPositiveButtonText = f"positive_{textOrId}"
|
|
else:
|
|
self._P._mPositiveButtonText = str(textOrId)
|
|
self._P._mPositiveButtonListener = listener
|
|
return self
|
|
|
|
def setNegativeButton(
|
|
self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(textOrId, int):
|
|
self._P._mNegativeButtonText = f"negative_{textOrId}"
|
|
else:
|
|
self._P._mNegativeButtonText = str(textOrId)
|
|
self._P._mNegativeButtonListener = listener
|
|
return self
|
|
|
|
def setNeutralButton(
|
|
self, textOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(textOrId, int):
|
|
self._P._mNeutralButtonText = f"neutral_{textOrId}"
|
|
else:
|
|
self._P._mNeutralButtonText = str(textOrId)
|
|
self._P._mNeutralButtonListener = listener
|
|
return self
|
|
|
|
def setCancelable(self, cancelable: bool) -> "AlertDialog.Builder":
|
|
self._P._mCancelable = cancelable
|
|
return self
|
|
|
|
def setOnCancelListener(self, listener: DialogInterface.OnCancelListener) -> "AlertDialog.Builder":
|
|
self._P._mCancelListener = listener
|
|
return self
|
|
|
|
def setOnDismissListener(self, listener: DialogInterface.OnDismissListener) -> "AlertDialog.Builder":
|
|
self._P._mDismissListener = listener
|
|
return self
|
|
|
|
def setOnKeyListener(self, listener: DialogInterface.OnKeyListener) -> "AlertDialog.Builder":
|
|
self._P._mKeyListener = listener
|
|
return self
|
|
|
|
def setItems(
|
|
self, itemsOrId: Any, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(itemsOrId, int):
|
|
self._P._mItems = [f"item_{itemsOrId}"]
|
|
else:
|
|
self._P._mItems = list(itemsOrId)
|
|
self._P._mItemClickListener = listener
|
|
return self
|
|
|
|
def setAdapter(
|
|
self, adapter: Any, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
self._P._mAdapter = adapter
|
|
self._P._mItemClickListener = listener
|
|
return self
|
|
|
|
def setSingleChoiceItems(
|
|
self, itemsOrId: Any, checkedItem: int, listener: Optional[DialogInterface.OnClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(itemsOrId, int):
|
|
self._P._mItems = [f"item_{itemsOrId}"]
|
|
else:
|
|
self._P._mItems = list(itemsOrId)
|
|
self._P._mCheckedItem = checkedItem
|
|
self._P._mItemClickListener = listener
|
|
return self
|
|
|
|
def setMultiChoiceItems(
|
|
self, itemsOrId: Any, checkedItems: Optional[List[bool]],
|
|
listener: Optional[DialogInterface.OnMultiChoiceClickListener] = None
|
|
) -> "AlertDialog.Builder":
|
|
if isinstance(itemsOrId, int):
|
|
self._P._mMultiChoiceItems = [f"item_{itemsOrId}"]
|
|
self._P._mCheckedItems = [False]
|
|
else:
|
|
self._P._mMultiChoiceItems = list(itemsOrId)
|
|
self._P._mCheckedItems = checkedItems or [False] * len(itemsOrId)
|
|
self._P._mMultiChoiceListener = listener
|
|
return self
|
|
|
|
def setView(self, viewOrRes: Any) -> "AlertDialog.Builder":
|
|
self._P._mView = viewOrRes
|
|
return self
|
|
|
|
def setInverseBackgroundForced(self, useInverse: bool) -> "AlertDialog.Builder":
|
|
self._P._mForceInverseBackground = useInverse
|
|
return self
|
|
|
|
def setRecycleOnMeasureEnabled(self, enabled: bool) -> "AlertDialog.Builder":
|
|
self._P._mRecycleOnMeasure = enabled
|
|
return self
|
|
|
|
def create(self) -> AlertDialog:
|
|
return self._P
|
|
|
|
def show(self) -> AlertDialog:
|
|
dialog = self.create()
|
|
dialog.show()
|
|
return dialog
|
|
|
|
def toString(self) -> str:
|
|
return f"AlertDialog.Builder(title={self._P._mTitle})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# CharacterPickerDialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class CharacterPickerDialog(Dialog):
|
|
"""CharacterPickerDialog — 字符选择对话框"""
|
|
|
|
def __init__(self, context: Any, view: Any, listener: Any, options: List[str], allowMultiple: bool):
|
|
super().__init__(context)
|
|
self._view = view
|
|
self._listener = listener
|
|
self._options = list(options)
|
|
self._allow_multiple = allowMultiple
|
|
self._selected_indices: List[int] = []
|
|
self._selected_characters: List[str] = []
|
|
|
|
def onClick(self, which: int) -> None:
|
|
if 0 <= which < len(self._options):
|
|
char = self._options[which]
|
|
if self._allow_multiple:
|
|
if which in self._selected_indices:
|
|
self._selected_indices.remove(which)
|
|
self._selected_characters.remove(char)
|
|
else:
|
|
self._selected_indices.append(which)
|
|
self._selected_characters.append(char)
|
|
else:
|
|
self._selected_indices = [which]
|
|
self._selected_characters = [char]
|
|
if self._listener:
|
|
self._listener(char)
|
|
|
|
def getSelectedCharacters(self) -> List[str]:
|
|
return list(self._selected_characters)
|
|
|
|
def toString(self) -> str:
|
|
return f"CharacterPickerDialog(options={len(self._options)}, multiple={self._allow_multiple})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# DatePickerDialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class DatePickerDialog(AlertDialog):
|
|
"""DatePickerDialog — 日期选择对话框"""
|
|
|
|
class OnDateSetListener(Stub):
|
|
"""DatePickerDialog.OnDateSetListener — 日期设置监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onDateSet(self, view: Any, year: int, month: int, dayOfMonth: int) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnDateSetListener"
|
|
|
|
def __init__(
|
|
self,
|
|
context: Any,
|
|
listener: Optional["DatePickerDialog.OnDateSetListener"] = None,
|
|
year: int = 2024,
|
|
month: int = 0,
|
|
dayOfMonth: int = 1,
|
|
):
|
|
super().__init__(context)
|
|
self._mListener = listener
|
|
self._mYear = year
|
|
self._mMonth = month
|
|
self._mDay = dayOfMonth
|
|
self._mMinDate: Optional[int] = None
|
|
self._mMaxDate: Optional[int] = None
|
|
self._mDatePicker: Optional[Any] = None
|
|
self._mTitle: Optional[str] = None
|
|
self._mInitialDate = datetime(year, month + 1, dayOfMonth)
|
|
|
|
def onDateChanged(self, view: Any, year: int, month: int, dayOfMonth: int) -> None:
|
|
self._mYear = year
|
|
self._mMonth = month
|
|
self._mDay = dayOfMonth
|
|
|
|
def getDatePicker(self) -> Optional[Any]:
|
|
return self._mDatePicker
|
|
|
|
def setOnDateSetListener(self, listener: "DatePickerDialog.OnDateSetListener") -> None:
|
|
self._mListener = listener
|
|
|
|
def updateDate(self, year: int, month: int, dayOfMonth: int) -> None:
|
|
self._mYear = year
|
|
self._mMonth = month
|
|
self._mDay = dayOfMonth
|
|
|
|
def getYear(self) -> int:
|
|
return self._mYear
|
|
|
|
def getMonth(self) -> int:
|
|
return self._mMonth
|
|
|
|
def getDayOfMonth(self) -> int:
|
|
return self._mDay
|
|
|
|
def setMinDate(self, minDate: int) -> None:
|
|
self._mMinDate = minDate
|
|
|
|
def setMaxDate(self, maxDate: int) -> None:
|
|
self._mMaxDate = maxDate
|
|
|
|
def getMinDate(self) -> Optional[int]:
|
|
return self._mMinDate
|
|
|
|
def getMaxDate(self) -> Optional[int]:
|
|
return self._mMaxDate
|
|
|
|
def show(self) -> None:
|
|
super().show()
|
|
if self._mListener:
|
|
self._mListener.onDateSet(None, self._mYear, self._mMonth, self._mDay)
|
|
|
|
def toString(self) -> str:
|
|
return f"DatePickerDialog({self._mYear}-{self._mMonth + 1:02d}-{self._mDay:02d})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# TimePickerDialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class TimePickerDialog(AlertDialog):
|
|
"""TimePickerDialog — 时间选择对话框"""
|
|
|
|
class OnTimeSetListener(Stub):
|
|
"""TimePickerDialog.OnTimeSetListener — 时间设置监听器"""
|
|
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def onTimeSet(self, view: Any, hourOfDay: int, minute: int) -> None:
|
|
pass
|
|
|
|
def toString(self) -> str:
|
|
return "OnTimeSetListener"
|
|
|
|
def __init__(
|
|
self,
|
|
context: Any,
|
|
listener: Optional["TimePickerDialog.OnTimeSetListener"] = None,
|
|
hourOfDay: int = 0,
|
|
minute: int = 0,
|
|
is24HourView: bool = True,
|
|
):
|
|
super().__init__(context)
|
|
self._mListener = listener
|
|
self._mHour = hourOfDay
|
|
self._mMinute = minute
|
|
self._mIs24HourView = is24HourView
|
|
self._mTimePicker: Optional[Any] = None
|
|
self._mTitle: Optional[str] = None
|
|
|
|
def onTimeChanged(self, view: Any, hourOfDay: int, minute: int) -> None:
|
|
self._mHour = hourOfDay
|
|
self._mMinute = minute
|
|
|
|
def getTimePicker(self) -> Optional[Any]:
|
|
return self._mTimePicker
|
|
|
|
def setOnTimeSetListener(self, listener: "TimePickerDialog.OnTimeSetListener") -> None:
|
|
self._mListener = listener
|
|
|
|
def updateTime(self, hourOfDay: int, minute: int) -> None:
|
|
self._mHour = hourOfDay
|
|
self._mMinute = minute
|
|
|
|
def getHour(self) -> int:
|
|
return self._mHour
|
|
|
|
def getMinute(self) -> int:
|
|
return self._mMinute
|
|
|
|
def is24HourView(self) -> bool:
|
|
return self._mIs24HourView
|
|
|
|
def show(self) -> None:
|
|
super().show()
|
|
if self._mListener:
|
|
self._mListener.onTimeSet(None, self._mHour, self._mMinute)
|
|
|
|
def toString(self) -> str:
|
|
return f"TimePickerDialog({self._mHour:02d}:{self._mMinute:02d})"
|
|
|
|
|
|
# ═══════════════════════════════════════════════════════════════
|
|
# ProgressDialog
|
|
# ═══════════════════════════════════════════════════════════════
|
|
|
|
class ProgressDialog(AlertDialog):
|
|
"""ProgressDialog — 进度对话框"""
|
|
|
|
STYLE_SPINNER = 0
|
|
STYLE_HORIZONTAL = 1
|
|
|
|
def __init__(self, context: Any):
|
|
super().__init__(context)
|
|
self._mProgressStyle = ProgressDialog.STYLE_SPINNER
|
|
self._mMax = 100
|
|
self._mProgress = 0
|
|
self._mSecondaryProgress = 0
|
|
self._mIndeterminate = False
|
|
self._mHasProgress = True
|
|
self._mProgressDrawable: Optional[Any] = None
|
|
self._mProgressNumber: Optional[str] = None
|
|
self._mProgressPercent: Optional[str] = None
|
|
self._mProgressNumberFormat = "%1d/%2d"
|
|
self._mProgressPercentFormat = "%.0f%%"
|
|
self._mCurrentProgressText: Optional[str] = None
|
|
self._mProgressTextColor = 0
|
|
self._mProgressBackgroundColor = 0
|
|
self._mMessageViewUpdate: bool = False
|
|
|
|
def getMax(self) -> int:
|
|
return self._mMax
|
|
|
|
def setMax(self, max: int) -> None:
|
|
self._mMax = max
|
|
|
|
def getProgress(self) -> int:
|
|
return self._mProgress
|
|
|
|
def setProgress(self, value: int) -> None:
|
|
self._mProgress = value
|
|
|
|
def getSecondaryProgress(self) -> int:
|
|
return self._mSecondaryProgress
|
|
|
|
def setSecondaryProgress(self, secondaryProgress: int) -> None:
|
|
self._mSecondaryProgress = secondaryProgress
|
|
|
|
def getProgressStyle(self) -> int:
|
|
return self._mProgressStyle
|
|
|
|
def setProgressStyle(self, style: int) -> None:
|
|
self._mProgressStyle = style
|
|
|
|
def isIndeterminate(self) -> bool:
|
|
return self._mIndeterminate
|
|
|
|
def setIndeterminate(self, indeterminate: bool) -> None:
|
|
self._mIndeterminate = indeterminate
|
|
|
|
def incrementProgressBy(self, diff: int) -> None:
|
|
self._mProgress = min(self._mProgress + diff, self._mMax)
|
|
|
|
def incrementSecondaryProgressBy(self, diff: int) -> None:
|
|
self._mSecondaryProgress += diff
|
|
|
|
def setProgressDrawable(self, drawable: Any) -> None:
|
|
self._mProgressDrawable = drawable
|
|
|
|
def setProgressNumberFormat(self, format: str) -> None:
|
|
self._mProgressNumberFormat = format
|
|
|
|
def setProgressPercentFormat(self, format: str) -> None:
|
|
self._mProgressPercentFormat = format
|
|
|
|
def onStart(self) -> None:
|
|
pass
|
|
|
|
def setMessage(self, message: str) -> None:
|
|
super().setMessage(message)
|
|
|
|
def show(
|
|
cls, context: Any, title: str, message: str, indeterminate: bool = True, cancelable: bool = False
|
|
) -> "ProgressDialog":
|
|
dialog = ProgressDialog(context)
|
|
dialog.setTitle(title)
|
|
dialog.setMessage(message)
|
|
dialog.setIndeterminate(indeterminate)
|
|
dialog.setCancelable(cancelable)
|
|
dialog.show()
|
|
return dialog
|
|
|
|
def toString(self) -> str:
|
|
return f"ProgressDialog(style={self._mProgressStyle}, progress={self._mProgress}/{self._mMax})" |