
RecyclerView. אחרי האישור הפרויקט נבנה מחדש.RecyclerView שתופס את כל המסך, עם id (recyclerViewDiamonds) ו-scroll bars אנכיים.item_diamond עם RelativeLayout. ImageView (80dp על 80dp), TextView לצבע (25sp) ו-TextView לקראט, עם תכונות tools להצגה במעצב בלבד. חשוב שהאלמנט הראשי יהיה RelativeLayout ולא LinearLayout.Diamond עם צבע (String) וקראט (float), גטרים וסטרים וקונסטרקטור שקורא ל-createRandomContent, שמגרילה אחד מחמישה צבעים: white, blue, green, pink, red.DiamondHolder extends RecyclerView.ViewHolder. הקונסטרקטור מקבל Context ו-View (itemView) ומאתר פעם אחת את שלושת הרכיבים. הפונקציה bindDiamond(Diamond) מציגה עליהם את הנתונים. המערכת יוצרת כמה Holders שיש פריטים על המסך._diamond, והמזהה נלקח עם getIdentifier. את הטקסט בונים עם String.format (עם %s ו-%.3f ct) במקום שרשור, כי כך נוצר פחות אובייקטי מחרוזת. הצבע נקבע דרך פונקציית עזר getColorValue, ו-white מוחלף באפור כדי שיהיה קריא על רקע לבן.DiamondsAdapter extends RecyclerView.Adapter<DiamondHolder>. הפונקציה onCreateViewHolder מנפחת את ה-layout ומחזירה Holder, ומתבצעת רק כמספר הפריטים הנראים. הפונקציה onBindViewHolder נקראת לכל פריט שמוצג ומפעילה bindDiamond. הפונקציה getItemCount מחזירה את גודל הרשימה.setLayoutManager, ממלאים 100 אובייקטי Diamond ומחברים setAdapter. עם LinearLayoutManager התצוגה כמו ListView, ועם GridLayoutManager (שתי עמודות) היא גריד.onCreateViewHolder נבעה מ-ClassCastException: ה-layout היה RelativeLayout והקוד המיר ל-LinearLayout.הטקסט המלא של הדקות הראשונות בהרצאה «Recycler View» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
בסרטונים הקודמים אנחנו השתמשנו עם רכיב הליסט ויו בכדי להציג רשימה של פריטים על המסך והכל עבד כמו שצריך והפריטים הוצגו בלי שום בעיה.
אבל קיימת איזושהי בעיית פרפורמנס מאוד בסיסית בנוגע לרכיב הליסט ויו. מה הבעיה? הרכיב ראינו שהוא מסוגל להציג איזשהו ליהאוט שאנחנו יכולים לבנות ולשים אותו בתיקיית הליהאוט.
עכשיו תארו לעצמכם מצב שיש לנו המון פריטים להצגה והיוזר יכול לבצע בעצם איזושהי גלילה ולראות עוד פריטים ועוד פריטים ועוד פריטים ברכיב הליסט-ויו, שזה כמובן משהו שיכול להיות.
איך רכיב הליסט-ויו עובד? כל פריט כזה שהוא הולך להציג הוא בעצם בונה עבורו את ה-Layout מקובץ ה-XML, כלומר הרכיב של הליסט-ויו מנפח עבורו את ה-Layout בכדי להכין מקום לכל הרכיבים הוויזואליים של ה-Layout.
הדבר הזה גוזל זמן רב יחסית מבחינת פרפורמנס. תארו לעצמכם יש לנו אלף אובייקטים, אלף פריטים ליתר דיוק ברשימה, ועכשיו עבור כל פריט ופריט המערכת מנפחת ליאוט נפרד, כאשר בכל רגע נתון לא באמת מוצגים אלף פריטים.
בואו נניח שמוצגים שישה פריטים, שבעה פריטים, עשרה פריטים, אבל עדיין מאחורי הקלעים מנופחים הלאאוטס השונים, כמובן כל פעם שמגיעים להציג פריט כזה אבל עדיין יש פה בזבוז של משאבי מערכת, בזבוז של זיכרון כי קובץ ה-XML כאילו נוצר מחדש עבור כל אחד
מהפריטים. אז יכול להיות מצב שיש הרבה פריטים ואנחנו גוללים ופתאום כל הליסט עובדת מאוד מאוד לאט כי ברקע המערכת או ה-List View ליתר דיוק יוצר את ה-Layouts האלה ומנפח אותם עבור כל אחד מהפריטים.
בסרטון הזה אנחנו הולכים לעבוד עם רכיב אחר לגמרי שנולד בשלב מאוחר יותר ובא לפתור בדיוק את הבעיה הזאת. הרכיב הזה נקרא Recycler View והסיבה שהוא נקרא Recycler View זה בגלל שהוא מבצע מה שנקרא Recycling.
מה שהרכיב הזה עושה הוא רואה כמה פריטים באמת צריכים להיות מוצגים על המסך אפילו שיש לי עוד המון פריטים אחרים ברשימה הוא לא מעניין אותו הוא מסתכל ואומר במסך עצמו אני רואה שאני צריך להציג נניח עשרה פריטים אז אני מבצע ניפוח רק של עשרה לייאאוטס וזהו.
עכשיו ברגע שהיוזר יבצע גלילה הוא לא מנפח עוד לייאאוטס אלא הוא משתמש בעשרת הלייאאוטס שהוא ניפח ומבצע ריסייקלינג עליהם. כלומר מה שהוא מאפשר לעשות זה רק להחליף את ה-UI עצמו כלומר את הדאטה שאנחנו רוצים להציג ולעדכן את אותם עשרה XMLים בצורה ציקלית כלומר בצורה סיבובית כזאת וכך הוא מבצע ניפוח רק
של מספר מצומצם של פריטים שמוצגים על המסך ולא ניפוח חוזר ונשנה של כל הפריטים שקיימים רק הדאטה הוא מחליף אותו אז בייסיקלי הוא יוצר נניח עשרה XMLים וכל הזמן רק אנחנו מחליפים את הדאטה שה-XML מציג ועדיין רואים שכל הזמן מגיעים פריטים חדשים.
אבל הפרפורמנס שלו יהפוך להיות מאוד גבוה ואנחנו נוכל ממש לבצע סקרולינג ולא לראות שהמידע נתקע אפילו שיש הרבה פריטים. אז בואו נראה איך אנחנו יכולים לעבוד עם ה-Recycler View. בגלל שה-Recycler View יתווסף בשלב מאוחר יותר אז אנחנו צריכים להוסיף אותו כרכיב חיצוני.
אז פעם ראשונה אנחנו הולכים לראות איך אנחנו מוסיפים רכיב חיצוני שנמצא במערכת. אז לצורך כך יש לנו את האייקון הזה כאן שנקרא Project Structure אפשר ללחוץ גם על Control Alt Shift ו-S והוא מאפשר לנו לשלב דברים חיצוניים.
אנחנו הולכים פה ל-Up ל-Dependencies לוחצים על הפלוס והולכים ל-Library Dependency בשביל לצרף איזושהי ספרייה חיצונית. בוחרים את הספרייה שנקראת Recycler.Vu יכול להיות שיש לכם גרסה יותר חדשה אפילו בואו נבצע אוקיי אנחנו רואים אותו כאן ובואו נבצע שוב פעם אוקיי והמערכת עכשיו מצרפת את הספרייה עם הרכיב הזה ותוך כדי זה גם עושה בילדינג
מחדש לפרויקט אנחנו יכולים לראות את זה כאן למטה וכך היא מאפשרת לנו עכשיו לעבוד עם הרכיב החדש הזה שלא היינו יכולים לעבוד איתו אם לא היינו מצרפים את הספרייה הזאת הנה אנחנו רואים שהוא סיים אנחנו יכולים לבוא לכאן ולבנות אובייקט ממנו.
בואו נתחיל לחפש RecyclerView ואנחנו רואים שהוא נמצא בתוך Android Support V7 Widget והוא נקרא RecyclerView אז בואו פשוט נחבר את זה, נגדיר שהוא יתפוס לנו את כל המסך, ניפטר רגע מזה, ניתן לו איזשהו ID כי אנחנו רוצים להתייחס אליו בקוד וה-edit שניתן לו זה RecyclerView ואנחנו הולכים
להציג המון המון פריטים והפריטים שאנחנו הולכים להציג זה תמונות וטקסט של יהלומים אז נקרא לו RecyclerViewDiamond דבר נוסף שאנחנו יכולים להגדיר זה Scroll Bars ונגדיר שהם יהיו ורטיקליים שאוטומטית יהיה לו Scroll Bar ורטיקלי בצורה כזאת.
אנחנו רוצים להציג בו בדיוק פריטים שונים שהם יהלומים בצבעים שונים ובוא נניח קרת שונה ושמות שונים אז הדבר הבא שאנחנו צריכים לעשות זה לארגן לעצמנו איזשהו layout שמראה איך להציג פריט בודד בדיוק כמו שעשינו עם ה-list view כאן אנחנו צריכים לגשת לתיקיית ה-layouts לצרף layout חדש בואו נקרא לו
אייטם underline diamond, נגדיר שהxml יהיה בצורה כזאת, ניקח רלטיב, נגדיר שאנחנו רוצים match parent עבור הוויד ו-wrap content עבור ה-height, בואו ניפטר מהוורטיקליות הזאת ששייכת ל-linear ולא ל-relative ועכשיו נגדיר מה אנחנו בעצם רוצים להציג.
אז בואו ניקח תמונה, נגדיר שוב פעם 80 dp 80 dp רוחב וגובה בואו ניתן לה id image view diamond בואו נגדיר לה margin 10 dps ובואו נגדיר tools.src ואנחנו צריכים בשלב הזה שיהיה לנו תמונות אז יש לנו כאן סדרה של תמונות נפסיק אותם, נחזור, נדביק בדרובל ובואו ניקח מתיקיית דרובל את רד דיימונד והנה יש לנו דיימונד
אחד. הדבר הבא שאנחנו רוצים להציג זה טקסט view, נגדיר אותו כ-Wrapped Content, בואו נגדיר ID טקסט view, נגדיר שאנחנו רוצים להציג את הצבע ונגדיר אותו כ-To Writeoff ID, אימג' ויו דיימונד כדי שהוא יהיה מימין נגדיר טקסט סייז 25 sp נגדיר מרג'ין 10 dps נגדיר טקסט קולור כ-red אבל אנחנו לא רוצים
שבאמת המערכת תשים לנו טקסט קולור רד מפני שאנחנו רוצים שאותו דיימונד אותו צבע נוכחי של הדיימונד יילקח ולכן אנחנו רוצים לשנות את זה לטולס אותו הדבר נגדיר tools.text.red.diamond יש לנו פה כל מיני צבעים שונים של יהלומים ומה שאנחנו רוצים זה שתוך כדי הריצה יהיה לנו המון המון המון אובייקטים של יהלומים שמוצגים עם תמונות שונות וצבעים
שונים אבל בזמן הדיזיין אנחנו רוצים שהדיזיינר רק יציג לנו כאילו איך זה הולך להיראות ולא באמת בזמן הריצה שהוא יתייחס לתכונות האלה.
את זה ראינו גם כשעבדנו עם ה-list view. בואו ניקח עוד text view אחד, נגדיר ID טקסט ויו וזה הכרת כלומר יחידת משקל של זהב ויהלומים ונגדיר שהוא נמצא בלואו ל-ID של טקסט ויו קולור ונגדיר שהוא נמצא על line left של ID טקסט ויו קולור אנחנו רוצים טקסט סייז
בואו ניקח 20 אנחנו רוצים טקסט כ... בואו ניתן לו משהו סתם דיפולטי כזה, 978 וטקסט סטייל.
שוב פעם את הטקסט, נהפוך ל-pools כדי שהוא לא יילקח בזמן הריצה. בואו נעביר רק את ה-bold הזה לכאן כשה-tools יהיה האחרון והנה יש לנו layout אחד שמגדיר לנו איך בעצם הולך להיראות פריט אחד שמתאר יהלום אחד טוב מה שאנחנו צריכים עכשיו לארגן זאת מחלקה שמתארת מה יש ביהלום כלומר מחלקת מידע טהורה אז בואו ניגש לקוד הג'אווה הנה יש לנו פה את המיינד אקטיביטי
ונוסיף מחלקה שמתארת דיימונד מה יש לדיימונד אחד לדיימונד אחד בואו ניקח private סטרינג קולור ויש לנו פרייבט פלוט קרת יחידת המשקל אנחנו צריכים גטרים וסטרים אז בואו נלחץ על אלט אינסרט נבחר גטרס אנד סטרס נסמן את שניהם והנה יש לנו גטרים וסטרים ואנחנו רוצים קונסטרקטור אלט אינסרט קונסטרקטור ואנחנו רוצים to select none למה
כי בואו נייצר את המידע של האובייקט כמידע דינמי ליתר דיוק רנדומלי ולכן בואו נייצר כאן איזושהי פונקציה נגדיר private void create random content ונקרא לה מתוך הקונסטרקטור הריק ככה ויהפוך לנו להתחיל להמציא כל מיני הגדרות בואו נגדיר שהפונקציה הזאת קודם כל נותנת מידע לקראת
ניגש ל-math.random ונגדיר שיש לנו פה איזשהו ערך רנדומלי מ-0 עד 10. לאחר מכן מבצע switch על math.random כפול 5 כי יש לנו רק חמישה סוגים שונים של יהלומים בצבעים שונים ובהתאם לערך הרנדומלי נתחיל להכניס את הצבעים אם יש לנו 0 אז color יקבל white בואו נשכפל את שלושת אלה ויש לנו כאן 1,
2, 3 ו-4, gray, white, יש לנו blue, לאחר מכן green, לאחר מכן בואו ניקח pink ולבסוף red.
והנה יש לנו אפשרות עכשיו לבנות אובייקט מסוג דיימונד שאוטומטית יש לו כל מיני נתונים רנדומליים שמכילים אותו.
אז אחרי שיש לנו את קובץ ה-Layout ה-XMLי שאומר איך להציג את המידע ויש לנו מחלקה שמתארת את המידע עצמו, השלב הבא יהיה לבנות את האדפטר בדיוק כמו שבנינו ב-List View.
אבל ב-Recycler View העניינים טיפה יותר מורכבים בכדי לאפשר את היעילות כך שהמערכת לא תייצר Layout XMLי עבור כל הפריטים אלא תייצר רק עבור הפריטים שמוצגים באותו רגע וכל פריט אחר רק יחליף את המידע שלו, אז חילקו את כל המערכת כאן לשני חלקים.
בכדי לייצר את האדפטר אנחנו צריכים ראשית לייצר שלב מקדים שנקרא הולדר. הולדר זאת מחלקה שרק אומרת איפה להציג את המידע. כלומר אם נותנים לה אובייקט דיימונד, אז כל מה שהיא עושה היא פשוט מציגה את הדאטה