Files
Android-pyApi/android_pyapi/android/widget_adapter.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

1145 lines
41 KiB
Python

"""
Android Widget Adapter 组件 — ListAdapter, SpinnerAdapter, ArrayAdapter (扩展),
CursorAdapter (扩展), RecyclerView.Adapter (扩展), RecyclerView.ViewHolder,
PagerAdapter, FragmentPagerAdapter, PagerTitleStrip 等
方法签名完全对齐 Android SDK
"""
from __future__ import annotations
from typing import Any, Callable, Dict, Generic, List, Optional, Tuple, TypeVar
from .._core import Stub, AndroidOnlyError
T = TypeVar("T")
__all__ = [
"ListAdapter", "SpinnerAdapter", "WrapperListAdapter",
"HeaderViewListAdapter", "ArrayAdapter", "CursorAdapter",
"SimpleCursorAdapter", "ResourceCursorAdapter", "SimpleAdapter",
"BaseAdapter", "RecyclerView",
"PagerAdapter", "FragmentPagerAdapter", "FragmentStatePagerAdapter",
"PagerTitleStrip", "PagerTabStrip",
]
# ═══════════════════════════════════════════════════════════════
# 适配器常量
# ═══════════════════════════════════════════════════════════════
ADAPTER_IGNORE_ITEM_VIEW_TYPE = -1
ADAPTER_NO_SELECTION = -1
ADAPTER_INVALID_POSITION = -1
ADAPTER_INVALID_ROW_ID = -1
ADAPTER_HAS_STABLE_IDS = True
ADAPTER_NO_STABLE_IDS = False
PAGER_POSITION_UNCHANGED = -1
PAGER_POSITION_NONE = -2
# ═══════════════════════════════════════════════════════════════
# BaseAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class BaseAdapter(Stub):
"""BaseAdapter — 基础适配器 (完整版)"""
def __init__(self):
super().__init__()
self._observers: List[Any] = []
def getCount(self) -> int:
return 0
def getItem(self, position: int) -> Optional[Any]:
return None
def getItemId(self, position: int) -> int:
return position
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
return None
def getItemViewType(self, position: int) -> int:
return ADAPTER_IGNORE_ITEM_VIEW_TYPE
def getViewTypeCount(self) -> int:
return 1
def hasStableIds(self) -> bool:
return False
def isEmpty(self) -> bool:
return self.getCount() == 0
def registerDataSetObserver(self, observer: Any):
self._observers.append(observer)
def unregisterDataSetObserver(self, observer: Any):
self._observers = [o for o in self._observers if o is not observer]
def notifyDataSetChanged(self):
for o in self._observers:
if hasattr(o, 'onChanged'):
o.onChanged()
def notifyDataSetInvalidated(self):
for o in self._observers:
if hasattr(o, 'onInvalidated'):
o.onInvalidated()
def areAllItemsEnabled(self) -> bool:
return True
def isEnabled(self, position: int) -> bool:
return True
def getDropDownView(self, position: int, convertView: Any, parent: Any) -> Any:
return self.getView(position, convertView, parent)
def toString(self) -> str:
return f"BaseAdapter(count={self.getCount()})"
def equals(self, other: Any) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
# ═══════════════════════════════════════════════════════════════
# ListAdapter
# ═══════════════════════════════════════════════════════════════
class ListAdapter(Stub):
"""ListAdapter — 列表适配器接口"""
def getCount(self) -> int:
return 0
def getItem(self, position: int) -> Optional[Any]:
return None
def getItemId(self, position: int) -> int:
return position
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
return None
def isEmpty(self) -> bool:
return self.getCount() == 0
def registerDataSetObserver(self, observer: Any):
pass
def unregisterDataSetObserver(self, observer: Any):
pass
def areAllItemsEnabled(self) -> bool:
return True
def isEnabled(self, position: int) -> bool:
return True
def getItemViewType(self, position: int) -> int:
return ADAPTER_IGNORE_ITEM_VIEW_TYPE
def getViewTypeCount(self) -> int:
return 1
def hasStableIds(self) -> bool:
return False
def toString(self) -> str:
return f"ListAdapter@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# SpinnerAdapter
# ═══════════════════════════════════════════════════════════════
class SpinnerAdapter(Stub):
"""SpinnerAdapter — 下拉适配器接口"""
def getCount(self) -> int:
return 0
def getItem(self, position: int) -> Optional[Any]:
return None
def getItemId(self, position: int) -> int:
return position
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
return None
def getDropDownView(self, position: int, convertView: Any, parent: Any) -> Any:
return self.getView(position, convertView, parent)
def toString(self) -> str:
return f"SpinnerAdapter@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# WrapperListAdapter
# ═══════════════════════════════════════════════════════════════
class WrapperListAdapter(Stub):
"""WrapperListAdapter — 包装列表适配器"""
def getWrappedAdapter(self) -> Optional[ListAdapter]:
return None
def getCount(self) -> int:
wrapped = self.getWrappedAdapter()
return wrapped.getCount() if wrapped else 0
def getItem(self, position: int) -> Optional[Any]:
wrapped = self.getWrappedAdapter()
return wrapped.getItem(position) if wrapped else None
def getItemId(self, position: int) -> int:
wrapped = self.getWrappedAdapter()
return wrapped.getItemId(position) if wrapped else position
def toString(self) -> str:
return f"WrapperListAdapter@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════════
# HeaderViewListAdapter
# ═══════════════════════════════════════════════════════════════
class HeaderViewListAdapter(WrapperListAdapter):
"""HeaderViewListAdapter — 页眉视图列表适配器"""
def __init__(self, wrappedAdapter: Optional[ListAdapter] = None):
super().__init__()
self._wrapped_adapter = wrappedAdapter
self._headers: List[Any] = []
self._footers: List[Any] = []
def getWrappedAdapter(self) -> Optional[ListAdapter]:
return self._wrapped_adapter
def addHeader(self, view: Any, data: Any = None, isSelectable: bool = True):
self._headers.append((view, data, isSelectable))
def addFooter(self, view: Any, data: Any = None, isSelectable: bool = True):
self._footers.append((view, data, isSelectable))
def removeHeader(self, view: Any) -> bool:
for i, (v, _, _) in enumerate(self._headers):
if v is view:
self._headers.pop(i)
return True
return False
def removeFooter(self, view: Any) -> bool:
for i, (v, _, _) in enumerate(self._footers):
if v is view:
self._footers.pop(i)
return True
return False
def getHeadersCount(self) -> int:
return len(self._headers)
def getFootersCount(self) -> int:
return len(self._footers)
def getCount(self) -> int:
count = len(self._headers) + len(self._footers)
if self._wrapped_adapter:
count += self._wrapped_adapter.getCount()
return count
def getItem(self, position: int) -> Optional[Any]:
if position < len(self._headers):
return self._headers[position][1]
offset = position - len(self._headers)
if self._wrapped_adapter and offset < self._wrapped_adapter.getCount():
return self._wrapped_adapter.getItem(offset)
footer_offset = offset - (self._wrapped_adapter.getCount() if self._wrapped_adapter else 0)
if 0 <= footer_offset < len(self._footers):
return self._footers[footer_offset][1]
return None
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
if position < len(self._headers):
return self._headers[position][0]
offset = position - len(self._headers)
if self._wrapped_adapter and offset < self._wrapped_adapter.getCount():
return self._wrapped_adapter.getView(offset, convertView, parent)
footer_offset = offset - (self._wrapped_adapter.getCount() if self._wrapped_adapter else 0)
if 0 <= footer_offset < len(self._footers):
return self._footers[footer_offset][0]
return None
def toString(self) -> str:
return f"HeaderViewListAdapter(headers={len(self._headers)}, footers={len(self._footers)})"
# ═══════════════════════════════════════════════════════════════
# ArrayAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class ArrayAdapter(BaseAdapter):
"""ArrayAdapter — 数组适配器 (完整版)"""
def __init__(self, context: Any = None, resource: int = 0,
textViewResourceId: int = 0, objects: List[Any] = None):
super().__init__()
self._context = context
self._resource = resource
self._text_view_resource_id = textViewResourceId
self._objects: List[Any] = list(objects) if objects else []
self._drop_down_resource = resource
self._field_id = 0
self._filter: Optional[Any] = None
def add(self, obj: Any):
self._objects.append(obj)
self.notifyDataSetChanged()
def addAll(self, *objects: Any):
for obj in objects:
self._objects.append(obj)
self.notifyDataSetChanged()
def insert(self, obj: Any, index: int):
self._objects.insert(index, obj)
self.notifyDataSetChanged()
def remove(self, obj: Any):
if obj in self._objects:
self._objects.remove(obj)
self.notifyDataSetChanged()
def clear(self):
self._objects.clear()
self.notifyDataSetChanged()
def sort(self, comparator: Callable[[Any, Any], int]):
self._objects.sort(key=lambda x: x)
self.notifyDataSetChanged()
def getCount(self) -> int:
return len(self._objects)
def getItem(self, position: int) -> Optional[Any]:
if 0 <= position < len(self._objects):
return self._objects[position]
return None
def getPosition(self, item: Any) -> int:
try:
return self._objects.index(item)
except ValueError:
return ADAPTER_INVALID_POSITION
def setDropDownViewResource(self, resource: int):
self._drop_down_resource = resource
def getDropDownViewResource(self) -> int:
return self._drop_down_resource
def getContext(self) -> Any:
return self._context
def getFilter(self) -> Optional[Any]:
return self._filter
def createFromResource(context: Any, textArrayResId: int,
textViewResId: int) -> "ArrayAdapter":
return ArrayAdapter(context=context, resource=textViewResId)
def toString(self) -> str:
return f"ArrayAdapter(count={len(self._objects)})"
# ═══════════════════════════════════════════════════════════════
# CursorAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class CursorAdapter(BaseAdapter):
"""CursorAdapter — 游标适配器 (完整版)"""
FLAG_AUTO_REQUERY = 0x01
FLAG_REGISTER_CONTENT_OBSERVER = 0x02
def __init__(self, context: Any = None, cursor: Any = None,
flags: int = FLAG_AUTO_REQUERY):
super().__init__()
self._context = context
self._cursor = cursor
self._flags = flags
self._row_id_column = "_id"
self._count = 0
if cursor:
self._count = len(cursor) if hasattr(cursor, '__len__') else 0
def getCursor(self) -> Any:
return self._cursor
def setCursor(self, cursor: Any):
self._cursor = cursor
self._count = len(cursor) if cursor and hasattr(cursor, '__len__') else 0
self.notifyDataSetChanged()
def getCount(self) -> int:
return self._count
def getItem(self, position: int) -> Optional[Any]:
if self._cursor and 0 <= position < self._count:
if hasattr(self._cursor, '__getitem__'):
return self._cursor[position]
return self._cursor
return None
def getItemId(self, position: int) -> int:
if self._cursor and 0 <= position < self._count:
item = self.getItem(position)
if item and hasattr(item, 'get'):
return int(item.get(self._row_id_column, position))
return position
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
return self.newView(self._context, self._cursor, parent) if not convertView else convertView
def newView(self, context: Any, cursor: Any, parent: Any) -> Any:
return None
def bindView(self, view: Any, context: Any, cursor: Any):
pass
def changeCursor(self, cursor: Any):
self.setCursor(cursor)
def getFilterQueryProvider(self) -> Optional[Any]:
return None
def setFilterQueryProvider(self, provider: Any):
pass
def runQueryOnBackgroundThread(self, constraint: str) -> Any:
return self._cursor
def toString(self) -> str:
return f"CursorAdapter(count={self._count})"
# ═══════════════════════════════════════════════════════════════
# SimpleCursorAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class SimpleCursorAdapter(CursorAdapter):
"""SimpleCursorAdapter — 简单游标适配器 (完整版)"""
def __init__(self, context: Any = None, layout: int = 0,
cursor: Any = None, fromColumns: List[str] = None,
toViews: List[int] = None, flags: int = 0):
super().__init__(context=context, cursor=cursor, flags=flags)
self._layout = layout
self._from_columns = fromColumns or []
self._to_views = toViews or []
def getLayout(self) -> int:
return self._layout
def setViewText(self, view: Any, text: str):
pass
def setViewImage(self, view: Any, value: str):
pass
def getStringConversionColumn(self) -> int:
return 0
def setStringConversionColumn(self, column: int):
pass
def getViewBinder(self) -> Optional[Any]:
return None
def setViewBinder(self, viewBinder: Any):
pass
def toString(self) -> str:
return f"SimpleCursorAdapter(layout={self._layout})"
# ═══════════════════════════════════════════════════════════════
# ResourceCursorAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class ResourceCursorAdapter(CursorAdapter):
"""ResourceCursorAdapter — 资源游标适配器 (完整版)"""
def __init__(self, context: Any = None, layout: int = 0,
cursor: Any = None, flags: int = 0,
dropDownLayout: int = 0):
super().__init__(context=context, cursor=cursor, flags=flags)
self._layout = layout
self._drop_down_layout = dropDownLayout or layout
def setDropDownViewResource(self, dropDownLayout: int):
self._drop_down_layout = dropDownLayout
def getDropDownView(self, position: int, convertView: Any, parent: Any) -> Any:
return self.newView(self._context, self._cursor, parent)
def toString(self) -> str:
return f"ResourceCursorAdapter(layout={self._layout})"
# ═══════════════════════════════════════════════════════════════
# SimpleAdapter (扩展)
# ═══════════════════════════════════════════════════════════════
class SimpleAdapter(BaseAdapter):
"""SimpleAdapter — 简单适配器 (完整版)"""
def __init__(self, context: Any = None, data: List[Dict[str, Any]] = None,
resource: int = 0, from_: List[str] = None,
to: List[int] = None):
super().__init__()
self._context = context
self._data = data or []
self._resource = resource
self._from_keys = from_ or []
self._to_ids = to or []
self._drop_down_resource = resource
def getCount(self) -> int:
return len(self._data)
def getItem(self, position: int) -> Optional[Dict[str, Any]]:
if 0 <= position < len(self._data):
return self._data[position]
return None
def getItemId(self, position: int) -> int:
return position
def getView(self, position: int, convertView: Any, parent: Any) -> Any:
return convertView
def setDropDownViewResource(self, resource: int):
self._drop_down_resource = resource
def getDropDownView(self, position: int, convertView: Any, parent: Any) -> Any:
return convertView
def getContext(self) -> Any:
return self._context
def getData(self) -> List[Dict[str, Any]]:
return list(self._data)
def setData(self, data: List[Dict[str, Any]]):
self._data = list(data)
self.notifyDataSetChanged()
def toString(self) -> str:
return f"SimpleAdapter(count={len(self._data)})"
# ═══════════════════════════════════════════════════════════════
# RecyclerView
# ═══════════════════════════════════════════════════════════════
class RecyclerView(Stub):
"""RecyclerView — 循环视图"""
HORIZONTAL = 0
VERTICAL = 1
NO_POSITION = -1
NO_ID = -1
INVALID_TYPE = -1
# ═══════════════════════════════════════════════════════════
# RecyclerView.Adapter (扩展)
# ═══════════════════════════════════════════════════════════
class Adapter(BaseAdapter):
"""RecyclerView.Adapter — RecyclerView 适配器 (完整版)"""
def __init__(self):
super().__init__()
self._has_stable_ids = False
self._state_restoration_policy = 0
self._observers: List[RecyclerView.AdapterDataObserver] = []
def onCreateViewHolder(self, parent: Any, viewType: int) -> "RecyclerView.ViewHolder":
raise NotImplementedError
def onBindViewHolder(self, holder: "RecyclerView.ViewHolder", position: int):
raise NotImplementedError
def getItemCount(self) -> int:
return 0
def getItemViewType(self, position: int) -> int:
return ADAPTER_IGNORE_ITEM_VIEW_TYPE
def setHasStableIds(self, hasStableIds: bool):
self._has_stable_ids = hasStableIds
def hasStableIds(self) -> bool:
return self._has_stable_ids
def onAttachedToRecyclerView(self, recyclerView: "RecyclerView"):
pass
def onDetachedFromRecyclerView(self, recyclerView: "RecyclerView"):
pass
def onViewAttachedToWindow(self, holder: "RecyclerView.ViewHolder"):
pass
def onViewDetachedFromWindow(self, holder: "RecyclerView.ViewHolder"):
pass
def onViewRecycled(self, holder: "RecyclerView.ViewHolder"):
pass
def onFailedToRecycleView(self, holder: "RecyclerView.ViewHolder") -> bool:
return False
def registerAdapterDataObserver(self, observer: "RecyclerView.AdapterDataObserver"):
self._observers.append(observer)
def unregisterAdapterDataObserver(self, observer: "RecyclerView.AdapterDataObserver"):
self._observers = [o for o in self._observers if o is not observer]
def notifyDataSetChanged(self):
for o in self._observers:
o.onChanged()
def notifyItemChanged(self, position: int):
for o in self._observers:
o.onItemRangeChanged(position, 1)
def notifyItemRangeChanged(self, positionStart: int, itemCount: int):
for o in self._observers:
o.onItemRangeChanged(positionStart, itemCount)
def notifyItemInserted(self, position: int):
for o in self._observers:
o.onItemRangeInserted(position, 1)
def notifyItemRangeInserted(self, positionStart: int, itemCount: int):
for o in self._observers:
o.onItemRangeInserted(positionStart, itemCount)
def notifyItemRemoved(self, position: int):
for o in self._observers:
o.onItemRangeRemoved(position, 1)
def notifyItemRangeRemoved(self, positionStart: int, itemCount: int):
for o in self._observers:
o.onItemRangeRemoved(positionStart, itemCount)
def notifyItemMoved(self, fromPosition: int, toPosition: int):
for o in self._observers:
o.onItemRangeMoved(fromPosition, toPosition, 1)
def getItemId(self, position: int) -> int:
return position
def toString(self) -> str:
return f"RecyclerView.Adapter(items={self.getItemCount()})"
# ═══════════════════════════════════════════════════════════
# RecyclerView.ViewHolder (扩展)
# ═══════════════════════════════════════════════════════════
class ViewHolder(Stub):
"""RecyclerView.ViewHolder — 视图持有者 (完整版)"""
def __init__(self, itemView: Any = None):
super().__init__()
self.itemView = itemView
self._adapter_position = RecyclerView.NO_POSITION
self._old_position = RecyclerView.NO_POSITION
self._item_id = RecyclerView.NO_ID
self._item_view_type = RecyclerView.INVALID_TYPE
self._is_recyclable = True
self._is_bound = False
def getAdapterPosition(self) -> int:
return self._adapter_position
def getOldPosition(self) -> int:
return self._old_position
def getItemId(self) -> int:
return self._item_id
def getItemViewType(self) -> int:
return self._item_view_type
def setIsRecyclable(self, recyclable: bool):
self._is_recyclable = recyclable
def isRecyclable(self) -> bool:
return self._is_recyclable
def setIsBound(self, bound: bool):
self._is_bound = bound
def isBound(self) -> bool:
return self._is_bound
def toString(self) -> str:
return f"ViewHolder(pos={self._adapter_position})"
def equals(self, other: Any) -> bool:
return self is other
def hashCode(self) -> int:
return id(self) & 0x7FFFFFFF
# ═══════════════════════════════════════════════════════════
# RecyclerView.LayoutManager (扩展)
# ═══════════════════════════════════════════════════════════
class LayoutManager(Stub):
"""RecyclerView.LayoutManager — 布局管理器 (完整版)"""
def __init__(self):
super().__init__()
self._child_count = 0
self._item_count = 0
self._auto_measure = True
def generateDefaultLayoutParams(self) -> Any:
return None
def onLayoutChildren(self, recycler: Any, state: Any):
pass
def getChildCount(self) -> int:
return self._child_count
def getItemCount(self) -> int:
return self._item_count
def setAutoMeasureEnabled(self, enabled: bool):
self._auto_measure = enabled
def isAutoMeasureEnabled(self) -> bool:
return self._auto_measure
def canScrollHorizontally(self) -> bool:
return False
def canScrollVertically(self) -> bool:
return False
def scrollToPosition(self, position: int):
pass
def smoothScrollToPosition(self, view: Any, state: Any, position: int):
pass
def computeVerticalScrollOffset(self, state: Any) -> int:
return 0
def computeVerticalScrollExtent(self, state: Any) -> int:
return 0
def computeVerticalScrollRange(self, state: Any) -> int:
return 0
def computeHorizontalScrollOffset(self, state: Any) -> int:
return 0
def computeHorizontalScrollExtent(self, state: Any) -> int:
return 0
def computeHorizontalScrollRange(self, state: Any) -> int:
return 0
def toString(self) -> str:
return f"LayoutManager(children={self._child_count})"
# ═══════════════════════════════════════════════════════════
# RecyclerView.AdapterDataObserver
# ═══════════════════════════════════════════════════════════
class AdapterDataObserver(Stub):
"""RecyclerView.AdapterDataObserver — 适配器数据观察者"""
def onChanged(self):
pass
def onItemRangeChanged(self, positionStart: int, itemCount: int):
pass
def onItemRangeInserted(self, positionStart: int, itemCount: int):
pass
def onItemRangeRemoved(self, positionStart: int, itemCount: int):
pass
def onItemRangeMoved(self, fromPosition: int, toPosition: int, itemCount: int):
pass
def toString(self) -> str:
return f"AdapterDataObserver@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════
# RecyclerView.ItemDecoration
# ═══════════════════════════════════════════════════════════
class ItemDecoration(Stub):
"""RecyclerView.ItemDecoration — 项目装饰"""
def onDraw(self, canvas: Any, parent: "RecyclerView", state: Any):
pass
def onDrawOver(self, canvas: Any, parent: "RecyclerView", state: Any):
pass
def getItemOffsets(self, outRect: Any, view: Any,
parent: "RecyclerView", state: Any):
outRect.set(0, 0, 0, 0)
def toString(self) -> str:
return f"ItemDecoration@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════
# RecyclerView.ItemAnimator
# ═══════════════════════════════════════════════════════════
class ItemAnimator(Stub):
"""RecyclerView.ItemAnimator — 项目动画器"""
def animateDisappearance(self, holder: ViewHolder, preInfo: Any,
postInfo: Any) -> bool:
return False
def animateAppearance(self, holder: ViewHolder, preInfo: Any,
postInfo: Any) -> bool:
return False
def animatePersistence(self, holder: ViewHolder, preInfo: Any,
postInfo: Any) -> bool:
return False
def animateChange(self, oldHolder: ViewHolder, newHolder: ViewHolder,
preInfo: Any, postInfo: Any) -> bool:
return False
def endAnimation(self, holder: ViewHolder):
pass
def endAnimations(self):
pass
def isRunning(self) -> bool:
return False
def dispatchAnimationsFinished(self):
pass
def toString(self) -> str:
return f"ItemAnimator@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════
# RecyclerView.SmoothScroller
# ═══════════════════════════════════════════════════════════
class SmoothScroller(Stub):
"""RecyclerView.SmoothScroller — 平滑滚动器"""
def start(self, recyclerView: "RecyclerView", layoutManager: LayoutManager,
targetPosition: int):
pass
def stop(self):
pass
def isRunning(self) -> bool:
return False
def getTargetPosition(self) -> int:
return RecyclerView.NO_POSITION
def toString(self) -> str:
return f"SmoothScroller@{hex(id(self))}"
# ═══════════════════════════════════════════════════════════
# RecyclerView.OnScrollListener
# ═══════════════════════════════════════════════════════════
class OnScrollListener(Stub):
"""RecyclerView.OnScrollListener — 滚动监听器"""
SCROLL_STATE_IDLE = 0
SCROLL_STATE_DRAGGING = 1
SCROLL_STATE_SETTLING = 2
def onScrollStateChanged(self, recyclerView: "RecyclerView", newState: int):
pass
def onScrolled(self, recyclerView: "RecyclerView", dx: int, dy: int):
pass
def toString(self) -> str:
return f"OnScrollListener@{hex(id(self))}"
def __init__(self):
super().__init__()
self._adapter: Optional[RecyclerView.Adapter] = None
self._layout_manager: Optional[RecyclerView.LayoutManager] = None
self._item_animator: Optional[RecyclerView.ItemAnimator] = None
self._scroll_listeners: List[RecyclerView.OnScrollListener] = []
self._item_decoration: Optional[RecyclerView.ItemDecoration] = None
def setAdapter(self, adapter: Adapter):
self._adapter = adapter
def getAdapter(self) -> Optional[Adapter]:
return self._adapter
def setLayoutManager(self, layoutManager: LayoutManager):
self._layout_manager = layoutManager
def getLayoutManager(self) -> Optional[LayoutManager]:
return self._layout_manager
def setItemAnimator(self, animator: ItemAnimator):
self._item_animator = animator
def getItemAnimator(self) -> Optional[ItemAnimator]:
return self._item_animator
def addItemDecoration(self, decoration: ItemDecoration, index: int = -1):
self._item_decoration = decoration
def addOnScrollListener(self, listener: OnScrollListener):
self._scroll_listeners.append(listener)
def removeOnScrollListener(self, listener: OnScrollListener):
self._scroll_listeners = [l for l in self._scroll_listeners if l is not listener]
def clearOnScrollListeners(self):
self._scroll_listeners.clear()
def scrollToPosition(self, position: int):
pass
def smoothScrollToPosition(self, position: int):
pass
def toString(self) -> str:
return f"RecyclerView(adapter={'set' if self._adapter else 'null'})"
# ═══════════════════════════════════════════════════════════════
# PagerAdapter
# ═══════════════════════════════════════════════════════════════
class PagerAdapter(Stub):
"""PagerAdapter — 页面适配器"""
POSITION_UNCHANGED = PAGER_POSITION_UNCHANGED
POSITION_NONE = PAGER_POSITION_NONE
def __init__(self):
super().__init__()
self._observers: List[Any] = []
def getCount(self) -> int:
return 0
def instantiateItem(self, container: Any, position: int) -> Any:
return None
def destroyItem(self, container: Any, position: int, obj: Any):
pass
def isViewFromObject(self, view: Any, obj: Any) -> bool:
return False
def getPageTitle(self, position: int) -> Optional[str]:
return None
def getPageWidth(self, position: int) -> float:
return 1.0
def getItemPosition(self, obj: Any) -> int:
return PagerAdapter.POSITION_UNCHANGED
def startUpdate(self, container: Any):
pass
def finishUpdate(self, container: Any):
pass
def registerDataSetObserver(self, observer: Any):
self._observers.append(observer)
def unregisterDataSetObserver(self, observer: Any):
self._observers = [o for o in self._observers if o is not observer]
def notifyDataSetChanged(self):
for o in self._observers:
if hasattr(o, 'onChanged'):
o.onChanged()
def toString(self) -> str:
return f"PagerAdapter(count={self.getCount()})"
# ═══════════════════════════════════════════════════════════════
# FragmentPagerAdapter
# ═══════════════════════════════════════════════════════════════
class FragmentPagerAdapter(PagerAdapter):
"""FragmentPagerAdapter — Fragment 页面适配器"""
BEHAVIOR_SET_USER_VISIBLE_HINT = 0
BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT = 1
def __init__(self, fm: Any = None, behavior: int = BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT):
super().__init__()
self._fm = fm
self._behavior = behavior
self._fragments: Dict[int, Any] = {}
def getItem(self, position: int) -> Any:
raise NotImplementedError
def instantiateItem(self, container: Any, position: int) -> Any:
fragment = self.getItem(position)
self._fragments[position] = fragment
return fragment
def destroyItem(self, container: Any, position: int, obj: Any):
self._fragments.pop(position, None)
def isViewFromObject(self, view: Any, obj: Any) -> bool:
if hasattr(obj, 'getView'):
return obj.getView() is view
return False
def getPageTitle(self, position: int) -> Optional[str]:
return None
def getItemId(self, position: int) -> int:
return position
def toString(self) -> str:
return f"FragmentPagerAdapter(count={self.getCount()})"
# ═══════════════════════════════════════════════════════════════
# FragmentStatePagerAdapter
# ═══════════════════════════════════════════════════════════════
class FragmentStatePagerAdapter(FragmentPagerAdapter):
"""FragmentStatePagerAdapter — Fragment 状态页面适配器"""
def __init__(self, fm: Any = None, behavior: int = FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT):
super().__init__(fm=fm, behavior=behavior)
self._saved_states: Dict[int, Any] = {}
def saveState(self, position: int) -> Any:
state = self._saved_states.get(position)
self._fragments.pop(position, None)
return state
def restoreState(self, state: Any, loader: Any):
pass
def instantiateItem(self, container: Any, position: int) -> Any:
return super().instantiateItem(container, position)
def destroyItem(self, container: Any, position: int, obj: Any):
state = self.saveState(position)
if state:
self._saved_states[position] = state
super().destroyItem(container, position, obj)
def toString(self) -> str:
return f"FragmentStatePagerAdapter(count={self.getCount()})"
# ═══════════════════════════════════════════════════════════════
# PagerTitleStrip / PagerTabStrip
# ═══════════════════════════════════════════════════════════════
class PagerTitleStrip(Stub):
"""PagerTitleStrip — 页面标题条"""
def __init__(self, context: Any = None):
super().__init__()
self._text_spacing = 16
self._nonprimary_alpha = 0.6
self._current_page = 0
self._adapter: Optional[PagerAdapter] = None
def setAdapter(self, adapter: PagerAdapter):
self._adapter = adapter
def getAdapter(self) -> Optional[PagerAdapter]:
return self._adapter
def setTextSpacing(self, spacingPixels: int):
self._text_spacing = spacingPixels
def getTextSpacing(self) -> int:
return self._text_spacing
def updateTitle(self, position: int, adapter: PagerAdapter):
self._current_page = position
def requestLayout(self):
pass
def toString(self) -> str:
return f"PagerTitleStrip(page={self._current_page})"
class PagerTabStrip(PagerTitleStrip):
"""PagerTabStrip — 页面标签条"""
def __init__(self, context: Any = None):
super().__init__(context=context)
self._tab_indicator_color = 0
self._tab_spacing = 8
self._draw_full_underline = False
self._underline_height = 2
self._tab_padding = 16
def setTabIndicatorColor(self, color: int):
self._tab_indicator_color = color
def getTabIndicatorColor(self) -> int:
return self._tab_indicator_color
def setDrawFullUnderline(self, draw: bool):
self._draw_full_underline = draw
def isDrawFullUnderline(self) -> bool:
return self._draw_full_underline
def setUnderlineHeight(self, height: int):
self._underline_height = height
def getUnderlineHeight(self) -> int:
return self._underline_height
def setTabPadding(self, padding: int):
self._tab_padding = padding
def getTabPadding(self) -> int:
return self._tab_padding
def toString(self) -> str:
return f"PagerTabStrip(page={self._current_page})"