יצירת רשימות דינמיות באמצעות RecyclerView חלק מ-Android Jetpack.
RecyclerView מאפשר להציג בקלות קבוצות גדולות של נתונים. אתם מספקים את הנתונים ומגדירים את המראה של כל פריט, וספריית RecyclerView יוצרת את הרכיבים באופן דינמי כשיש צורך בהם.
כפי שרומז השם, רכיב RecyclerView ממחזר את הרכיבים הבודדים האלה. כשגלילים פריטים מחוץ למסך, רכיב RecyclerView לא משמיד את התצוגה שלהם. במקום זאת, RecyclerView משתמש שוב בתצוגה לפריטים חדשים שגללו למסך. רכיב RecyclerView משפר את הביצועים ואת תגובת האפליקציה, וגם מפחית את צריכת החשמל.
כיתות מפתח
כמה כיתות פועלות יחד כדי ליצור את הרשימה הדינמית שלכם.
RecyclerView
הוא ה-ViewGroup
שמכיל את הצפיות שמתאימות לנתונים שלכם. הוא עצמו תצוגה, כך שאפשר להוסיף אתRecyclerView
לפריסה כמו שמוסיפים כל רכיב אחר של ממשק המשתמש.כל רכיב ברשימה מוגדר באמצעות אובייקט view holder. כשה-ViewHolder נוצר, לא משויכים אליו נתונים. אחרי שיוצרים את מחזיק התצוגה, ה-
RecyclerView
מקשר אותו לנתונים שלו. מגדירים את ה-ViewHolder על ידי הרחבה שלRecyclerView.ViewHolder
.ה-
RecyclerView
מבקש תצוגות מפורטות, ומקשר את התצוגות לנתונים שלהן באמצעות קריאה ל-methods במתאם. מגדירים את המתאם על ידי הרחבה של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
קורא ל-method הזה בכל פעם שהוא צריך ליצור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, אפשר לעיין במקורות המידע הבאים.