העברת RecyclerView לרשימת 'עצלים'

RecyclerView הוא רכיב תצוגה שמאפשר להציג בקלות קבוצות גדולות של נתונים. במקום ליצור תצוגות לכל פריט בקבוצת הנתונים, RecyclerView משפר את הביצועים של האפליקציה על ידי שמירה על מאגר קטן של תצוגות ושימוש חוזר בהן בזמן הגלילה בין הפריטים.

בחלונית הכתיבה, אפשר להשתמש ברשימות 'לאט' כדי להשיג את אותו הדבר. בדף הזה מוסבר איך להעביר את ההטמעה של RecyclerView כך שתשתמש ברשימות 'עיכוב קריאה' ב-Compose.

שלבי ההעברה

כדי להעביר את ההטמעה של RecyclerView ל-Compose:

  1. מסמנים את ה-RecyclerView בהערה או מסירים אותו מההיררכיה של ממשק המשתמש, ומוסיפים ComposeView כדי להחליף אותו, אם הוא עדיין לא נמצא בהיררכיה. זהו המאגר של הרשימה הלא פעילה שתוסיפו:

          <FrameLayout
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    
      <!--    <androidx.recyclerview.widget.RecyclerView-->
      <!--            android:id="@+id/recycler_view"-->
      <!--            android:layout_width="match_parent"-->
      <!--            android:layout_height="match_parent />"-->
    
              <androidx.compose.ui.platform.ComposeView
                  android:id="@+id/compose_view"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
    
          </FrameLayout>
    
  2. קובעים איזה סוג של Lazy list composable נדרש על סמך מנהל הפריסה של RecyclerView (ראו טבלה בהמשך). הרכיב הניתן לקישור שתבחרו יהיה הרכיב ברמה העליונה של ComposeView שהוספתם בשלב הקודם.

    LayoutManager

    קומפוזיציה

    LinearLayoutManager

    LazyColumn או LazyRow

    GridLayoutManager

    LazyVerticalGrid או LazyHorizontalGrid

    StaggeredGridLayoutManager

    LazyVerticalStaggeredGrid או LazyHorizontalStaggeredGrid

    // recyclerView.layoutManager = LinearLayoutManager(context)
    composeView.setContent {
        LazyColumn(Modifier.fillMaxSize()) {
            // We use a LazyColumn since the layout manager of the RecyclerView is a vertical LinearLayoutManager
        }
    }

  3. יוצרים רכיב מורכב תואם לכל סוג תצוגה בהטמעה של RecyclerView.Adapter. בדרך כלל כל סוג תצוגה ממופה למחלקת משנה של ViewHolder, אבל זה לא תמיד המצב. הרכיבים האלה ישמשו לייצוג של סוגי רכיבים שונים ברשימה בממשק המשתמש:

    @Composable
    fun ListItem(data: MyData, modifier: Modifier = Modifier) {
        Row(modifier.fillMaxWidth()) {
            Text(text = data.name)
            // … other composables required for displaying `data`
        }
    }

    הלוגיקה שבשיטות onCreateViewHolder() ו-onBindViewHolder() של RecyclerView.Adapter תוחלף ברכיבי ה-Composable האלה ובמצב שתספקו להם. ב-Compose אין הפרדה בין יצירת רכיב מורכב לפריט לבין קישור נתונים אליו – המושגים האלה משולבים.

  4. בתוך החריץ content של הרשימה העצלה (פרמטר הלמבדה העוקב), משתמשים בפונקציה items() (או בעלת עומס יתר מקביל) כדי לבצע איטרציה על הנתונים של הרשימה. ב-lambda‏ itemContent, מפעילים את הפריט המתאים לנתונים שלכם:

    val data = listOf<MyData>(/* ... */)
    composeView.setContent {
        LazyColumn(Modifier.fillMaxSize()) {
            items(data) {
                ListItem(it)
            }
        }
    }

תרחישים נפוצים לדוגמה

קישוטים של פריטים

ב-RecyclerView יש את המושג ItemDecoration, שבעזרתו אפשר להוסיף ציור מיוחד לפריטים ברשימה. לדוגמה, אפשר להוסיף את התו ItemDecoration כדי להוסיף מפרידים בין פריטים:

val itemDecoration = DividerItemDecoration(recyclerView.context, LinearLayoutManager.VERTICAL)
recyclerView.addItemDecoration(itemDecoration)

ל-Compose אין מושג מקביל של עיטורי פריטים. במקום זאת, אפשר להוסיף את כל קישוטי ממשק המשתמש ברשימה ישירות בהרכבה. לדוגמה, כדי להוסיף לרשימת רכיבים קווים מפרידים, אפשר להשתמש ברכיב ה-composable Divider אחרי כל פריט:

LazyColumn(Modifier.fillMaxSize()) {
    itemsIndexed(data) { index, d ->
        ListItem(d)
        if (index != data.size - 1) {
            HorizontalDivider()
        }
    }
}

אנימציות של פריטים

אפשר להגדיר ItemAnimator ב-RecyclerView כדי להציג אנימציה של הפריטים כשמבצעים שינויים במתאם. כברירת מחדל, RecyclerView משתמש ב-DefaultItemAnimator, שמספק אנימציות בסיסיות באירועי הסרה, הוספה והזזה.

הרעיון של רשימות מושכות (lazy) דומה, באמצעות המאפיין animateItemPlacement. מידע נוסף זמין במאמר אנימציות של פריטים.

מקורות מידע נוספים

למידע נוסף על העברת RecyclerView ל-Compose, תוכלו לעיין במקורות המידע הבאים: