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

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

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

שלבי ההעברה

כדי להעביר את ההטמעה של RecyclerView לפיתוח נייטיב, פועלים לפי השלבים הבאים:

  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 (ראו את הטבלה שבהמשך). ה-composable שתבחרו יהיה ה-composable ברמה העליונה של ה-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 תוחלף על ידי ה-composables האלה והמצב שאתם מספקים להם. ב-Compose, אין הפרדה בין יצירת פונקציה קומפוזבילית לפריט לבין קישור נתונים אליה – המושגים האלה משולבים.

  4. במשבצת content של הרשימה הנטענת לפי הצורך (הפרמטר lambda בסוף), משתמשים בפונקציה 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, שמספק אנימציות בסיסיות באירועים של הסרה, הוספה והעברה.

לרשימות עם טעינה מדורגת יש קונספט דומה באמצעות המשנה animateItemPlacement. מידע נוסף זמין במאמר בנושא אנימציות של פריטים.

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

למידע נוסף על העברת RecyclerView לפיתוח נייטיב, אפשר לעיין במקורות המידע הבאים: