יצירת רשימות דינמיות באמצעות RecyclerView חלק מ-Android Jetpack.
RecyclerView מאפשר להציג בקלות קבוצות גדולות של נתונים. אתם מספקים את הנתונים ומגדירים את המראה של כל פריט, וספריית RecyclerView יוצרת את הרכיבים באופן דינמי כשיש צורך בהם.
כפי שרומז השם, רכיב RecyclerView ממחזר את הרכיבים הבודדים האלה. כשגלילים פריטים מחוץ למסך, רכיב RecyclerView לא משמיד את התצוגה שלהם. במקום זאת, RecyclerView משתמש שוב בתצוגה לפריטים חדשים שגללו למסך. רכיב RecyclerView משפר את הביצועים ואת תגובת האפליקציה, וגם מפחית את צריכת החשמל.
כיתות מפתח
כמה כיתות פועלות יחד כדי ליצור את הרשימה הדינמית.
RecyclerView
הואViewGroup
שמכיל את התצוגות שמתאימות לנתונים שלכם. הוא עצמו תצוגה, כך שמוסיפים אתRecyclerView
למבנה כמו שמוסיפים כל רכיב אחר של ממשק המשתמש.כל רכיב בנפרד ברשימה מוגדר על ידי אובייקט view holder. כשה-ViewHolder נוצר, לא משויכים אליו נתונים. אחרי שיוצרים את מחזיק התצוגה, ה-
RecyclerView
מקשר אותו לנתונים שלו. מגדירים את ה-ViewHolder על ידי הרחבה שלRecyclerView.ViewHolder
.ה-
RecyclerView
מבקש תצוגות ומקשר את התצוגות לנתונים שלהן, על ידי קריאה לשיטות במתאם. מגדירים את המתאם על ידי הרחבה שלRecyclerView.Adapter
.מנהל הפריסה מסדר את הרכיבים השונים ברשימה. אפשר להשתמש באחד מנהלי הפריסה שסופקו על ידי ספריית RecyclerView, או להגדיר מנהל משלכם. כל מנהלי הפריסות מבוססים על הכיתה המופשטת
LayoutManager
של הספרייה.
אתם יכולים לראות איך כל החלקים מתחברים באפליקציית הדוגמה של RecyclerView (Kotlin) או באפליקציית הדוגמה של RecyclerView (Java).
שלבים להטמעת RecyclerView
אם אתם מתכננים להשתמש ב-RecyclerView, יש כמה דברים שצריך לעשות. הם מוסברים בפירוט בקטעים הבאים.
קובעים איך תיראה הרשימה או התצוגה של הרשת. בדרך כלל אפשר להשתמש באחד מנהלי הפריסה הרגילים של ספריית RecyclerView.
עיצוב המראה וההתנהגות של כל רכיב ברשימה. על סמך העיצוב הזה, מרחיבים את המחלקה
ViewHolder
. הגרסה שלכם ל-ViewHolder
מספקת את כל הפונקציונליות של הפריטים ברשימה. ה-ViewHolder הוא מעטפת שלView
, והתצוגה הזו מנוהלת על ידיRecyclerView
.מגדירים את
Adapter
שמשויך לנתונים שלכם עם התצוגותViewHolder
.
יש גם אפשרויות התאמה אישית מתקדמות שמאפשרות להתאים את RecyclerView לצרכים הספציפיים שלכם.
תכנון הפריסה
הפריטים ב-RecyclerView מסודרים לפי הקלאס LayoutManager
. בספרייה RecyclerView יש שלושה מנהלי פריסה שמטפלים בתרחישים הנפוצים ביותר של פריסה:
LinearLayoutManager
מסדרת את הפריטים ברשימה חד-מימדית.GridLayoutManager
הפריטים מסודרים ברשת דו-מימדית:- אם התצוגה של התרשים היא אנכית, המערכת מנסה להגדיר לכל הרכיבים בכל שורה את אותו רוחב וגובה, אבל לגובה של שורות שונות יכולים להיות ערכים שונים.
GridLayoutManager
- אם התצוגה של הרשת היא אופקית, המערכת מנסה להגדיר לכל הרכיבים בכל עמודה את אותו רוחב וגובה, אבל לעמודות שונות יכולים להיות רוחבים שונים.
GridLayoutManager
- אם התצוגה של התרשים היא אנכית, המערכת מנסה להגדיר לכל הרכיבים בכל שורה את אותו רוחב וגובה, אבל לגובה של שורות שונות יכולים להיות ערכים שונים.
StaggeredGridLayoutManager
דומה ל-GridLayoutManager
, אבל לא נדרש שהפריטים בשורה יהיו באותו גובה (לרשתות אנכיות) או שהפריטים באותה עמודה יהיו באותו רוחב (לרשתות אופקיות). כתוצאה מכך, הפריטים בשורה או בעמודה יכולים להיות מוסטים זה מזה.
בנוסף, צריך לעצב את הפריסה של הפריטים הבודדים. תצטרכו את הפריסה הזו כשאתם מעצבים את ה-view holder, כפי שמתואר בקטע הבא.
הטמעת המתאם והמחזיק של התצוגה
אחרי שתבחרו את הפריסה, תצטרכו להטמיע את Adapter
ו-ViewHolder
. שתי הכיתות האלה פועלות יחד כדי לקבוע את אופן הצגת הנתונים. ה-ViewHolder
הוא עטיפה של View
שמכילה את הפריסה של פריט ספציפי ברשימה. ה-Adapter
יוצר אובייקטים מסוג ViewHolder
לפי הצורך, ומגדיר את הנתונים של התצוגות האלה. תהליך השיוך של תצוגות לנתונים שלהן נקרא קישור.
כשמגדירים את המתאם, משנים את ברירת המחדל של שלוש שיטות מפתח:
onCreateViewHolder()
: RecyclerView
קורא לשיטה הזו בכל פעם שהוא צריך ליצורViewHolder
חדש. השיטה יוצרת ומפעילה אתViewHolder
ואתView
המשויך אליו, אבל לא ממלאת את התוכן של התצוגה –ViewHolder
עדיין לא משויך לנתונים ספציפיים.onBindViewHolder()
:RecyclerView
קורא ל-method הזה כדי לשייך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, אפשר לעיין במקורות המידע הבאים.