יצירת הטמעה עם ממשקי API ישנים
קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
בשיעור הזה נסביר איך ליצור הטמעה שמשקפת ממשקי API חדשים יותר ועדיין תומכת במכשירים ישנים.
בוחרים פתרון חלופי
המשימה המאתגרת ביותר בשימוש בתכונות חדשות יותר של ממשק המשתמש באופן תואם לאחור היא להחליט ולהטמיע פתרון ישן (חלופה) לגרסאות ישנות יותר של הפלטפורמה. במקרים רבים אפשר להשתמש בתכונות ישנות של framework של ממשק משתמש כדי למלא את המטרה של הרכיבים החדשים האלה בממשק המשתמש. לדוגמה:
בדרך כלל אין פתרון אחד שמתאים לכולם להעברה לאחור של רכיבים חדשים יותר בממשק המשתמש במכשירים ישנים. חשוב לשים לב לחוויית המשתמש: במכשירים ישנים, יכול להיות שהמשתמשים לא מכירים את דפוסי העיצוב ואת רכיבי ממשק המשתמש החדשים יותר. נסו לחשוב איך אפשר להשתמש באלמנטים המוכרים כדי לספק את אותה פונקציונליות. במקרים רבים זה פחות מדאיג – אם רכיבי ממשק המשתמש החדשים בולטים יותר בסביבה העסקית של האפליקציה (כמו סרגל הפעולות), או שבהם מודל האינטראקציה פשוט ואינטואיטיבי במיוחד (כמו תצוגות החלקה באמצעות ViewPager
).
הטמעת כרטיסיות באמצעות ממשקי API ישנים יותר
כדי ליצור הטמעה ישנה יותר של כרטיסיות בסרגל הפעולות, אפשר להשתמש ב-TabWidget
וב-TabHost
(אבל אפשר להשתמש בווידג'טים של Button
בפריסה אופקית). צריך ליישם את האפשרות הזו במחלקות שנקראות TabHelperEclair
ו-CompatTabEclair
, כי ההטמעה הזו מתבססת על ממשקי API שהושקו לא יאוחר מ-Android 2.0 (Eclair).
איור 1. תרשים מחלקה להטמעת Eclair של כרטיסיות.
ההטמעה של CompatTabEclair
שומרת מאפייני כרטיסייה, כמו הטקסט והסמל של הכרטיסייה במשתני מכונה, כי אין אובייקט ActionBar.Tab
זמין לטיפול באחסון הזה:
Kotlin
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.)
}
Java
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
אובייקטים ומחווני כרטיסיות:
Kotlin
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.
}
Java
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 ישנים. בשיעור הבא נדון בשימוש בהטמעות האלה באפליקציה שלכם.
דוגמאות התוכן והקוד שבדף הזה כפופות לרישיונות המפורטים בקטע רישיון לתוכן. Java ו-OpenJDK הם סימנים מסחריים או סימנים מסחריים רשומים של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-07-27 (שעון UTC).
[[["התוכן קל להבנה","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-27 (שעון UTC)."],[],[],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."]]