ViewPager2
הוא גרסה משופרת של ספריית ViewPager
שמציעה
פונקציונליות משופרת ומשרתת התמודדות עם קשיים נפוצים בשימוש ב-ViewPager
.
אם האפליקציה שלך כבר משתמשת בViewPager
, כדאי לקרוא את הדף הזה כדי לקבל מידע נוסף על
העברה אל ViewPager2
.
אם ברצונך להשתמש ב-ViewPager2
באפליקציה וכרגע אתה לא משתמש בה
ViewPager
, לקרוא את המאמר החלקה בין מקטעים באמצעות
ViewPager2 ו-יצירת תצוגות החלקה עם
כרטיסיות באמצעות ViewPager2
מידע.
יתרונות המעבר ל-ViewPager2
הסיבה העיקרית להעברה היא שהדומיין ViewPager2
פעיל
תמיכה בפיתוח, ו-ViewPager
לא. עם זאת, ViewPager2
מציע גם
כמה יתרונות ספציפיים נוספים.
תמיכה בכיוון אנכי
ב-ViewPager2
יש תמיכה בעימוד אנכי בנוסף לפורמט אופקי מסורתי
החלוקה לדפים. אפשר להפעיל את הדפדוף האנכי של רכיב ViewPager2
באמצעות הגדרת
מאפיין android:orientation
:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:orientation="vertical" />
אפשר להגדיר את המאפיין הזה באופן פרוגרמטי באמצעות setOrientation() .
תמיכה מימין לשמאל
ב-ViewPager2
יש תמיכה בחלוקה לדפים מימין לשמאל (RTL). החלוקה לדפים בפורמט RTL מופעלת
באופן אוטומטי בהתאם למיקום, אך ניתן גם באופן ידני
להפעיל חלוקה לדפים מימין לרכיב ViewPager2
על ידי הגדרת
מאפיין android:layoutDirection
:
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layoutDirection="rtl" />
אפשר להגדיר את המאפיין הזה באופן פרוגרמטי באמצעות setLayoutDirection() .
אוספי מקטעים שניתנים לשינוי
ב-ViewPager2
יש תמיכה בהחלפה של אוסף מקטעים שאפשר לשנות,
שיחות
notifyDatasetChanged()
כדי לעדכן את ממשק המשתמש כשהאוסף הבסיסי משתנה.
פירוש הדבר הוא שהאפליקציה שלך יכולה לשנות באופן דינמי את אוסף המקטעים
סביבת זמן הריצה, ו-ViewPager2
יציג בצורה נכונה את האוסף שהשתנה.
DiffUtil
ViewPager2
מבוסס על RecyclerView
,
כלומר, יש לו גישה
כלי השירות DiffUtil
בכיתה. יש לכך כמה יתרונות, אבל בעיקר
ViewPager2
אובייקטים מנצלים במקור את האנימציות של השינויים במערך הנתונים
מהכיתה RecyclerView
.
העברת האפליקציה אל ViewPager2
כדי לעדכן ViewPager
אובייקטים באפליקציה ל-ViewPager2
:
עדכון קובצי פריסת XML
קודם כול, מחליפים את רכיבי ViewPager
בקובצי הפריסה של XML
רכיבי ViewPager2
:
<!-- A ViewPager element -->
<android.support.v4.view.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- A ViewPager2 element -->
<androidx.viewpager2.widget.ViewPager2
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
עדכון מחלקות מתאמים
כשהשתמשת ב-ViewPager
, היה עליך להרחיב את סוג המתאם
סופקו דפים חדשים לאובייקט. בהתאם לתרחיש לדוגמה, נעשה שימוש ב-ViewPager
בשלושה סיווגים מופשטים שונים. בפונקציה ViewPager2
יש רק שני מחלקות מופשטות.
לכל אובייקט ViewPager
שממירים לאובייקט ViewPager2
,
מעדכנים את מחלקת המתאם כדי להרחיב את המחלקה המופשטת המתאימה באופן הבא:
- כאשר נעשה שימוש ב-
PagerAdapter
כדי לעבור לצפיות בדפים על ידיViewPager
, יש להשתמש ב-RecyclerView.Adapter
עםViewPager2
. - כש
ViewPager
השתמש/ה ב-FragmentPagerAdapter
כדי לעבור בין דפים מספר קבוע של מקטעים, יש להשתמש ב-FragmentStateAdapter
עםViewPager2
. - כאשר
ViewPager
השתמש/ה ב-FragmentStatePagerAdapter
כדי לעבור בין דפים מספר גדול או לא ידוע של מקטעים, יש להשתמש ב-FragmentStateAdapter
עםViewPager2
.
פרמטרים של בונה
סוגי מתאמים מבוססי מקטעים יורשים מ-FragmentPagerAdapter
או
FragmentStatePagerAdapter
תמיד מקבל אובייקט FragmentManager
יחיד
בתור פרמטר constructor. עם הארכה של FragmentStateAdapter
למשך
סוג המתאם ViewPager2
, יש את האפשרויות הבאות ל-constructor
במקום זאת:
- האובייקט
FragmentActivity
או האובייקטFragment
שבו נמצא אובייקטViewPager2
. ברוב המקרים זו האפשרות הטובה ביותר. - אובייקט
FragmentManager
ואובייקטLifecycle
.
סוגי מתאמים מבוססי-תצוגה שעוברים בירושה ישירות מ-RecyclerView.Adapter
לא דורשים פרמטר של constructor.
שיטות לשינוי מברירת המחדל
סיווגי המתאם צריכים גם לשנות שיטות שונות עבור ViewPager2
מאשר במשך ViewPager
:
- במקום
getCount()
, משנים אתgetItemCount()
. מלבד השם, השיטה הזו לא השתנתה. - במקום
getItem()
, צריך לשנות אתcreateFragment()
בגרסה שמבוססת על מקטעים של סוגי מתאמים. חשוב לוודא ששיטת הcreateFragment()
החדשה תמיד פועלת מספקת מופע מקטע חדש בכל פעם קוראים לפונקציה במקום שימוש חוזר במכונות.
סיכום
לסיכום, כדי להמיר סיווג מתאם ViewPager
לשימוש עם ViewPager2
,
עליך לבצע את השינויים הבאים:
- לשנות את מחלקת העל ל-
RecyclerView.Adapter
כדי לעבור בין תצוגות, אוFragmentStateAdapter
כדי לעבור בין מקטעים. - שינוי הפרמטרים של ה-constructor בסוגי מתאמים שמבוססים על מקטעים.
- שינוי
getItemCount()
במקוםgetCount()
. - ביטול של
createFragment()
במקוםgetItem()
במתאם שמבוסס על מקטעים הסוגים.
Kotlin
// A simple ViewPager adapter class for paging through fragments class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = NUM_PAGES override fun getItem(position: Int): Fragment = ScreenSlidePageFragment() } // An equivalent ViewPager2 adapter class class ScreenSlidePagerAdapter(fa: FragmentActivity) : FragmentStateAdapter(fa) { override fun getItemCount(): Int = NUM_PAGES override fun createFragment(position: Int): Fragment = ScreenSlidePageFragment() }
Java
// A simple ViewPager adapter class for paging through fragments public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { public ScreenSlidePagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { return new ScreenSlidePageFragment(); } @Override public int getCount() { return NUM_PAGES; } } // An equivalent ViewPager2 adapter class private class ScreenSlidePagerAdapter extends FragmentStateAdapter { public ScreenSlidePagerAdapter(FragmentActivity fa) { super(fa); } @Override public Fragment createFragment(int position) { return new ScreenSlidePageFragment(); } @Override public int getItemCount() { return NUM_PAGES; } }
ארגון מחדש של ממשקי TabLayout
ViewPager2
חדש: שינויים בשילוב של TabLayout
. אם
משתמש כרגע ב-ViewPager
עם אובייקט TabLayout
כדי להציג פורמט אופקי
כרטיסיות לניווט, צריך לארגן מחדש את האובייקט TabLayout
שילוב עם ViewPager2
.
הקישור TabLayout
בוטל מ-ViewPager2
והוא זמין עכשיו כחלק מ
רכיבי החומר. כלומר, כדי להשתמש בו צריך להוסיף
את התלות המתאימה בקובץ build.gradle
שלכם:
מגניב
implementation "com.google.android.material:material:1.1.0-beta01"
Kotlin
implementation("com.google.android.material:material:1.1.0-beta01")
צריך לשנות גם את המיקום של הרכיב TabLayout
בהיררכיה של
בקובץ פריסת ה-XML. עם ViewPager
, הרכיב TabLayout
מוצהר בתור
צאצא של הרכיב ViewPager
; אבל עם ViewPager2
, הרכיב TabLayout
מוצהר ישירות מעל הרכיב ViewPager2
, באותה רמה:
<!-- A ViewPager element with a TabLayout -->
<androidx.viewpager.widget.ViewPager
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</androidx.viewpager.widget.ViewPager>
<!-- A ViewPager2 element with a TabLayout -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
לסיום, צריך לעדכן את הקוד שמצרף את האובייקט TabLayout
אל
אובייקט ViewPager
. בעוד ש-TabLayout
משתמש ב-setupWithViewPager()
משלו
לשילוב עם ViewPager
, היא דורשת TabLayoutMediator
לאינטגרציה עם ViewPager2
.
האובייקט TabLayoutMediator
מטפל גם במשימה של יצירת כותרות דפים
עבור האובייקט TabLayout
, כלומר שסיווג המתאם לא צריך
לשנות את getPageTitle()
:
Kotlin
// Integrating TabLayout with ViewPager class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) tabLayout.setupWithViewPager(viewPager) } ... } class DemoCollectionPagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) { override fun getCount(): Int = 4 override fun getPageTitle(position: Int): CharSequence { return "OBJECT ${(position + 1)}" } ... } // Integrating TabLayout with ViewPager2 class CollectionDemoFragment : Fragment() { ... override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tabLayout = view.findViewById(R.id.tab_layout) TabLayoutMediator(tabLayout, viewPager) { tab, position -> tab.text = "OBJECT ${(position + 1)}" }.attach() } ... }
Java
// Integrating TabLayout with ViewPager public class CollectionDemoFragment extends Fragment { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); tabLayout.setupWithViewPager(viewPager); } ... } public class DemoCollectionPagerAdapter extends FragmentStatePagerAdapter { ... @Override public int getCount() { return 4; } @Override public CharSequence getPageTitle(int position) { return "OBJECT " + (position + 1); } ... } // Integrating TabLayout with ViewPager2 public class CollectionDemoFragment : Fragment() { ... @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { TabLayout tabLayout = view.findViewById(R.id.tab_layout); new TabLayoutMediator(tabLayout, viewPager, (tab, position) -> tab.setText("OBJECT " + (position + 1)) ).attach(); } ... }
תמיכה ברכיבים מקוננים שניתן לגלול
ב-ViewPager2
אין תמיכה בתצוגות גלילה מקוננות במקרים שבהם
לתצוגת הגלילה יש כיוון זהה לזה של האובייקט ViewPager2
שמכיל
את זה. לדוגמה, לא ניתן לגלול בתצוגת גלילה אנכית בתוך
אובייקט ViewPager2
שמכוון אנכית.
כדי לתמוך בתצוגת גלילה בתוך אובייקט ViewPager2
באותו כיוון,
צריך להתקשר
requestDisallowInterceptTouchEvent()
באובייקט ViewPager2
כאשר
לצפות לגלילה אל הרכיב שהוצב בו במקום זאת. הגלילה הפנימית בViewPager2
מדגים דרך אחת לפתרון הבעיה הזו באמצעות
פריסת wrapper מותאמת אישית.
מקורות מידע נוספים
מידע נוסף על ViewPager2
זמין במקורות המידע הנוספים הבאים.
דוגמיות
- דוגמאות ViewPager2 ב-GitHub
סרטונים
- הפיכת הדף: מעבר ל-ViewPager2 (כנס המפתחים של Android לשנת 2019)