یک پیاده سازی با API های قدیمی ایجاد کنید
با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
این درس نحوه ایجاد پیادهسازی را مورد بحث قرار میدهد که منعکسکننده APIهای جدیدتر و در عین حال از دستگاههای قدیمیتر پشتیبانی میکند.
در مورد راه حل جایگزین تصمیم بگیرید
چالش برانگیزترین کار در استفاده از ویژگی های رابط کاربری جدیدتر به روشی سازگار با عقب، تصمیم گیری و اجرای یک راه حل قدیمی تر (fallback) برای نسخه های پلتفرم قدیمی تر است. در بسیاری از موارد، این امکان وجود دارد که هدف این مؤلفههای رابط کاربری جدیدتر با استفاده از ویژگیهای چارچوب رابط کاربری قدیمیتر محقق شود. به عنوان مثال:
نوارهای اقدام را می توان با استفاده از یک LinearLayout
افقی حاوی دکمه های تصویر، یا به عنوان نوار عنوان سفارشی یا به عنوان نما در طرح بندی فعالیت شما، پیاده سازی کرد. اقدامات سرریز را می توان در زیر دکمه منوی دستگاه ارائه کرد.
برگههای Action Bar را میتوان با استفاده از یک LinearLayout
افقی حاوی دکمهها یا با استفاده از عنصر TabWidget
UI پیادهسازی کرد.
ویجت های NumberPicker
و Switch
را می توان به ترتیب با استفاده از ابزارک های Spinner
و ToggleButton
پیاده سازی کرد.
ویجت های ListPopupWindow
و PopupMenu
را می توان با استفاده از ابزارک های PopupWindow
پیاده سازی کرد.
به طور کلی راه حل یکسانی برای پسپورت کردن اجزای رابط کاربری جدیدتر به دستگاههای قدیمیتر وجود ندارد. مراقب تجربه کاربری باشید: در دستگاه های قدیمی تر، کاربران ممکن است با الگوهای طراحی جدیدتر و اجزای رابط کاربری آشنا نباشند. به این فکر کنید که چگونه می توان همان عملکرد را با استفاده از عناصر آشنا ارائه کرد. در بسیاری از موارد، این موضوع کمتر نگران کننده است - اگر اجزای رابط کاربری جدیدتر در اکوسیستم برنامه برجسته باشند (مانند نوار عمل)، یا مدل تعامل بسیار ساده و شهودی باشد (مانند نماها با کشیدن انگشت با استفاده از ViewPager
).
تب ها را با استفاده از API های قدیمی پیاده سازی کنید
برای ایجاد یک پیادهسازی قدیمیتر از برگههای نوار عمل، میتوانید از TabWidget
و TabHost
استفاده کنید (اگرچه میتوانید از ویجتهای Button
با چیدمان افقی استفاده کنید). این را در کلاسهایی به نامهای TabHelperEclair
و CompatTabEclair
پیادهسازی کنید، زیرا این پیادهسازی از APIهایی استفاده میکند که حداکثر تا Android 2.0 (Eclair) معرفی شدهاند.

شکل 1. نمودار کلاس برای اجرای Eclair زبانه ها.
پیاده سازی CompatTabEclair
ویژگی های برگه مانند متن برگه و نماد را در متغیرهای نمونه ذخیره می کند، زیرا یک شی ActionBar.Tab
برای مدیریت این ذخیره سازی موجود نیست:
کاتلین
class CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :
CompatTab(tag) {
// Store these properties in the instance,
// as there is no ActionBar.Tab object.
private var text: CharSequence? = null
...
override fun setText(resId: Int): CompatTab {
// Our older implementation simply stores this
// information in the object instance.
text = activity.resources.getText(resId)
return this
}
...
// Do the same for other properties (icon, callback, etc.)
}
جاوا
public class CompatTabEclair extends CompatTab {
// Store these properties in the instance,
// as there is no ActionBar.Tab object.
private CharSequence text;
...
public CompatTab setText(int resId) {
// Our older implementation simply stores this
// information in the object instance.
text = activity.getResources().getText(resId);
return this;
}
...
// Do the same for other properties (icon, callback, etc.)
}
پیاده سازی TabHelperEclair
از روش هایی در ویجت TabHost
برای ایجاد اشیاء TabHost.TabSpec
و نشانگرهای برگه استفاده می کند:
کاتلین
class TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {
private var tabHost: TabHost? = null
...
override fun setUp() {
// Our activity layout for pre-Honeycomb devices
// must contain a TabHost.
tabHost = tabHost ?: mActivity.findViewById<TabHost>(android.R.id.tabhost).apply {
setup()
}
}
override fun addTab(tab: CompatTab) {
...
tabHost?.newTabSpec(tab.tag)?.run {
setIndicator(tab.getText()) // And optional icon
...
tabHost?.addTab(this)
}
}
// The other important method, newTab() is part of
// the base implementation.
}
جاوا
public class TabHelperEclair extends TabHelper {
private TabHost tabHost;
...
protected void setUp() {
if (tabHost == null) {
// Our activity layout for pre-Honeycomb devices
// must contain a TabHost.
tabHost = (TabHost) mActivity.findViewById(
android.R.id.tabhost);
tabHost.setup();
}
}
public void addTab(CompatTab tab) {
...
TabSpec spec = tabHost
.newTabSpec(tag)
.setIndicator(tab.getText()); // And optional icon
...
tabHost.addTab(spec);
}
// The other important method, newTab() is part of
// the base implementation.
}
اکنون دو پیادهسازی CompatTab
و TabHelper
دارید: یکی که روی دستگاههای دارای Android نسخه 3.0 یا بالاتر کار میکند و از APIهای جدید استفاده میکند، و دیگری که روی دستگاههای دارای Android نسخه 2.0 یا بالاتر کار میکند و از APIهای قدیمیتر استفاده میکند. درس بعدی استفاده از این پیاده سازی ها در برنامه شما را مورد بحث قرار می دهد.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[[["درک آسان","easyToUnderstand","thumb-up"],["مشکلم را برطرف کرد","solvedMyProblem","thumb-up"],["غیره","otherUp","thumb-up"]],[["اطلاعاتی که نیاز دارم وجود ندارد","missingTheInformationINeed","thumb-down"],["بیشازحد پیچیده/ مراحل بسیار زیاد","tooComplicatedTooManySteps","thumb-down"],["قدیمی","outOfDate","thumb-down"],["مشکل ترجمه","translationIssue","thumb-down"],["مشکل کد / نمونهها","samplesCodeIssue","thumb-down"],["غیره","otherDown","thumb-down"]],["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Create an implementation with older APIs\n\nThis lesson discusses how to create an implementation that mirrors newer APIs yet supports older devices.\n\nDecide on a substitute solution\n-------------------------------\n\nThe most challenging task in using newer UI features in a backward-compatible way is deciding on and implementing an older (fallback) solution for older platform versions. In many cases, it's possible to fulfill the purpose of these newer UI components using older UI framework features. For example:\n\n- Action bars can be implemented using a horizontal [LinearLayout](/reference/android/widget/LinearLayout) containing image buttons, either as custom title bars or as views in your activity layout. Overflow actions can be presented under the device *Menu* button.\n\n- Action bar tabs can be implemented using a horizontal [LinearLayout](/reference/android/widget/LinearLayout) containing buttons, or using the [TabWidget](/reference/android/widget/TabWidget) UI element.\n\n- [NumberPicker](/reference/android/widget/NumberPicker) and [Switch](/reference/android/widget/Switch) widgets can be implemented using [Spinner](/reference/android/widget/Spinner) and [ToggleButton](/reference/android/widget/ToggleButton) widgets, respectively.\n\n- [ListPopupWindow](/reference/android/widget/ListPopupWindow) and [PopupMenu](/reference/android/widget/PopupMenu) widgets can be implemented using [PopupWindow](/reference/android/widget/PopupWindow) widgets.\n\nThere generally isn't a one-size-fits-all solution for backporting newer UI components to older devices. Be mindful of the user experience: on older devices, users may not be familiar with newer design patterns and UI components. Give some thought as to how the same functionality can be delivered using familiar elements. In many cases this is less of a concern---if newer UI components are prominent in the application ecosystem (such as the action bar), or where the interaction model is extremely simple and intuitive (such as swipe views using a [ViewPager](/reference/androidx/viewpager/widget/ViewPager)).\n\nImplement tabs using older APIs\n-------------------------------\n\nTo create an older implementation of action bar tabs, you can use a [TabWidget](/reference/android/widget/TabWidget) and [TabHost](/reference/android/widget/TabHost) (although one can alternatively use horizontally laid-out [Button](/reference/android/widget/Button) widgets). Implement this in classes called `TabHelperEclair` and `CompatTabEclair`, since this implementation uses APIs introduced no later than Android 2.0 (Eclair).\n\n**Figure 1.** Class diagram for the Eclair implementation of tabs.\n\nThe `CompatTabEclair` implementation stores tab properties such as the tab text and icon in instance variables, since there isn't an [ActionBar.Tab](/reference/android/app/ActionBar.Tab) object available to handle this storage: \n\n### Kotlin\n\n```kotlin\nclass CompatTabEclair internal constructor(val activity: FragmentActivity, tag: String) :\n CompatTab(tag) {\n\n // Store these properties in the instance,\n // as there is no ActionBar.Tab object.\n private var text: CharSequence? = null\n ...\n\n override fun setText(resId: Int): CompatTab {\n // Our older implementation simply stores this\n // information in the object instance.\n text = activity.resources.getText(resId)\n return this\n }\n\n ...\n // Do the same for other properties (icon, callback, etc.)\n}\n```\n\n### Java\n\n```java\npublic class CompatTabEclair extends CompatTab {\n // Store these properties in the instance,\n // as there is no ActionBar.Tab object.\n private CharSequence text;\n ...\n\n public CompatTab setText(int resId) {\n // Our older implementation simply stores this\n // information in the object instance.\n text = activity.getResources().getText(resId);\n return this;\n }\n\n ...\n // Do the same for other properties (icon, callback, etc.)\n}\n```\n\nThe `TabHelperEclair` implementation makes use of methods on the\n[TabHost](/reference/android/widget/TabHost) widget for creating [TabHost.TabSpec](/reference/android/widget/TabHost.TabSpec)\nobjects and tab indicators: \n\n### Kotlin\n\n```kotlin\nclass TabHelperEclair internal constructor(activity: FragmentActivity) : TabHelper(activity) {\n\n private var tabHost: TabHost? = null\n ...\n\n override fun setUp() {\n // Our activity layout for pre-Honeycomb devices\n // must contain a TabHost.\n tabHost = tabHost ?: mActivity.findViewById\u003cTabHost\u003e(android.R.id.tabhost).apply {\n setup()\n }\n }\n\n override fun addTab(tab: CompatTab) {\n ...\n tabHost?.newTabSpec(tab.tag)?.run {\n setIndicator(tab.getText()) // And optional icon\n ...\n tabHost?.addTab(this)\n }\n }\n // The other important method, newTab() is part of\n // the base implementation.\n}\n```\n\n### Java\n\n```java\npublic class TabHelperEclair extends TabHelper {\n private TabHost tabHost;\n ...\n\n protected void setUp() {\n if (tabHost == null) {\n // Our activity layout for pre-Honeycomb devices\n // must contain a TabHost.\n tabHost = (TabHost) mActivity.findViewById(\n android.R.id.tabhost);\n tabHost.setup();\n }\n }\n\n public void addTab(CompatTab tab) {\n ...\n TabSpec spec = tabHost\n .newTabSpec(tag)\n .setIndicator(tab.getText()); // And optional icon\n ...\n tabHost.addTab(spec);\n }\n\n // The other important method, newTab() is part of\n // the base implementation.\n}\n```\n\nYou now have two implementations of `CompatTab` and `TabHelper`: one that works on devices running Android 3.0 or later and uses new APIs, and another that works on devices running Android 2.0 or later and uses older APIs. The next lesson discusses using these implementations in your application."]]