יצירת רשימות דינמיות באמצעות RecyclerView חלק מ-Android Jetpack.

רוצה לנסות את שיטת הכתיבה?
'Jetpack פיתוח נייטיב' היא ערכת הכלים המומלצת לממשק המשתמש ל-Android. הסבר איך עובדים עם פריסות ב'כתיבה'.

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

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

סיווגי מפתחות

כמה כיתות פועלות יחד כדי ליצור את הרשימה הדינמית שלכם.

  • RecyclerView הערך ViewGroup מכיל את הצפיות שתואם לנתונים שלכם. מדובר בתצוגה עצמה, לכן צריך להוסיף את RecyclerView לפריסה, כמו שמוסיפים כל רכיב אחר של ממשק המשתמש.

  • כל רכיב ברשימה מוגדר באמצעות אובייקט view holder. מתי בעל התצוגה המפורטת נוצר, ולא משויכים לו נתונים. אחרי בעל התצוגה המפורטת נוצר, ה-RecyclerView מקשר אותו לנתונים שלו. שלך להגדיר את בעל התצוגה באמצעות הרחבה RecyclerView.ViewHolder

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

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

אפשר לראות איך כל החלקים משתלבים ביחד באפליקציה לדוגמה של RecyclerView (קוטלין) או אפליקציה לדוגמה של RecyclerView (Java).

שלבים להטמעת RecyclerView

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

  1. בוחרים את מראה הרשימה או הרשת. בדרך כלל אפשר להשתמש באחד ממנהלי הפריסה הרגילים של ספריית RecyclerView.

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

  3. צריך להגדיר את ה-Adapter שמשייך את הנתונים לתצוגות של ViewHolder.

יש גם התאמה אישית מתקדמת חדשות שמאפשרות לך להתאים אישית RecyclerView במיוחד לצרכים שלך.

תכנון הפריסה

הפריטים ב-RecyclerView מסודרים לפי LayoutManager בכיתה. בספריית RecyclerView יש שלושה מנהלי פריסה, שאחראים מצבי הפריסה הנפוצים ביותר:

  • LinearLayoutManager מארגנת את הפריטים ברשימה חד-ממדית.
  • GridLayoutManager מארגנת את הפריטים ברשת דו-ממדית:
    • אם הרשת מאורגנת אנכית, GridLayoutManager מנסה ליצור את כל לרכיבים בכל שורה יש רוחב וגובה זהים, אבל שורות שונות יכולים להיות בגובה שונים.
    • אם הרשת מסודרת לרוחב, GridLayoutManager ינסה לבצע את כל הפעולות לרכיבים בכל עמודה יש אותו רוחב וגובה, אך יכולים להיות ברוחב שונה של העמודות.
  • StaggeredGridLayoutManager דומה ל-GridLayoutManager, אבל לא מחייב את הפריטים לשורה יש גובה זהה (ברשתות אנכיות) או פריטים באותה עמודה. להיות באותו רוחב (לרשתות אופקיות). התוצאה היא שהפריטים בשורה או בעמודה יכולות לקזז זו את זו.

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

הטמעת המתאם ומחזיק התצוגה

לאחר שקובעים את הפריסה, צריך להטמיע את Adapter וגם ViewHolder. שני הסוגים האלה פועלים יחד כדי להגדיר את אופן הפעולה של הנתונים מוצגת. ViewHolder הוא wrapper מסביב ל-View שמכיל את לפריסה של פריט בודד ברשימה. השדה Adapter יוצר ViewHolder אובייקטים לפי הצורך וגם מגדירה את הנתונים עבור התצוגות האלה. התהליך של שיוך הצפיות לנתונים שלהם נקרא קישור.

כשמגדירים את המתאם, אפשר לשנות שלוש שיטות עיקריות:

  • onCreateViewHolder(): RecyclerView יקרא לשיטה הזו בכל פעם צריך ליצור ViewHolder חדש. השיטה יוצרת ומאתחלת את ViewHolder וה-View המשויך אליו, אבל לא ממלא את תוכן - ViewHolder עדיין לא קושר לנתונים ספציפיים.

  • onBindViewHolder(): הפקודה RecyclerView מפעילה את השיטה הזו כדי לשייך ViewHolder לנתונים. שמאחזר את הנתונים המתאימים ומשתמשת בנתונים כדי למלא את הפריסה של בעל האתר. לדוגמה, אם ב-RecyclerView מוצגת רשימה של שמות, השיטה עשויה למצוא את השם המתאים ברשימה ולמלא את התצוגה לווידג'ט TextView של הבעלים.

  • getItemCount(): הפונקציה RecyclerView מפעילה את השיטה הזו כדי לקבל את הגודל של מערך הנתונים. לדוגמה, ביישום של פנקס כתובות, זה עשוי להיות המספר הכולל של הכתובות. ההגדרה הזו משמשת את RecyclerView כדי לקבוע מתי אין עוד פריטים שאפשר להשתמש בהם מוצגת.

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

Kotlin


class CustomAdapter(private val dataSet: Array<String>) :
        RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val textView: TextView

        init {
            // Define click listener for the ViewHolder's View
            textView = view.findViewById(R.id.textView)
        }
    }

    // Create new views (invoked by the layout manager)
    override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
        // Create a new view, which defines the UI of the list item
        val view = LayoutInflater.from(viewGroup.context)
                .inflate(R.layout.text_row_item, viewGroup, false)

        return ViewHolder(view)
    }

    // Replace the contents of a view (invoked by the layout manager)
    override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.textView.text = dataSet[position]
    }

    // Return the size of your dataset (invoked by the layout manager)
    override fun getItemCount() = dataSet.size

}

Java


public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> {

    private String[] localDataSet;

    /**
     * Provide a reference to the type of views that you are using
     * (custom ViewHolder)
     */
    public static class ViewHolder extends RecyclerView.ViewHolder {
        private final TextView textView;

        public ViewHolder(View view) {
            super(view);
            // Define click listener for the ViewHolder's View

            textView = (TextView) view.findViewById(R.id.textView);
        }

        public TextView getTextView() {
            return textView;
        }
    }

    /**
     * Initialize the dataset of the Adapter
     *
     * @param dataSet String[] containing the data to populate views to be used
     * by RecyclerView
     */
    public CustomAdapter(String[] dataSet) {
        localDataSet = dataSet;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        // Create a new view, which defines the UI of the list item
        View view = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.text_row_item, viewGroup, false);

        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // Get element from your dataset at this position and replace the
        // contents of the view with that element
        viewHolder.getTextView().setText(localDataSet[position]);
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return localDataSet.length;
    }
}

הפריסה של כל פריט בתצוגה מוגדרת בקובץ פריסת XML, כרגיל. במקרה כזה, באפליקציה יש קובץ text_row_item.xml כמו:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="@dimen/list_item_height"
    android:layout_marginLeft="@dimen/margin_medium"
    android:layout_marginRight="@dimen/margin_medium"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/element_text"/>
</FrameLayout>

השלבים הבאים

בקטע הקוד הבא מוסבר איך להשתמש ב-RecyclerView.

Kotlin


class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val dataset = arrayOf("January", "February", "March")
        val customAdapter = CustomAdapter(dataset)

        val recyclerView: RecyclerView = findViewById(R.id.recycler_view)
        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.adapter = customAdapter

    }

}

Java


RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.layoutManager = new LinearLayoutManager(this)
recyclerView.setAdapter(customAdapter);

בספרייה יש גם דרכים רבות להתאים אישית את ההטמעה. לקבלת מידע נוסף מידע נוסף ראו RecyclerView מתקדם התאמה אישית.

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

למידע נוסף על בדיקות ב-Android, אפשר לעיין במקורות המידע הבאים.

אפליקציות לדוגמה