
setOnItemClickListener כמו ב-ListView, ויתרון הדבר הוא שאפשר לדעת גם על מה בתוך הפריט המשתמש לחץ: תמונה, טקסט או הרקע. כדי לדווח על כך משתמשים ב-Listener Design Pattern, ובשיעור מטמיעים אותו ברשימת היהלומים.interface OnDiamondClickListener עם ארבע פונקציות: onColorClick(colorName), onCaratClick(carat), onImageClick(imageId) ו-onBackgroundClick(diamond).listener ופונקציה setOnDiamondClickListener. מתכנת שלא רוצה לקבל דיווחים פשוט לא קורא לה.setOnClickListener על itemView (הרקע), על התמונה ועל שני ה-TextView. כל אחד קורא לפונקציה המתאימה של ה-listener.listener != null, כי אסור לקרוא לפונקציה על null. זה נוהג מקובל בכל האירועים.bindDiamond שומרים את ה-Diamond הנוכחי בשדה, כדי שאפשר יהיה לדווח עליו בלחיצה על הרקע.getImageIdFromImageName מוציאה את החישוב של מזהה התמונה, כך שהקוד לא חוזר על עצמו.DiamondsAdapter יש אותו שדה ואותה פונקציה רישום, מסוג DiamondHolder.OnDiamondClickListener. ב-onCreateViewHolder יוצרים את ה-Holder, קוראים ל-setOnDiamondClickListener עם ה-listener ומחזירים אותו.diamond.toString() (נוצר ב-Alt+Insert).getColorValue עברה למחלקת Diamond כפונקציה public static, כי היא לא משתמשת בשדות של אובייקט.הטקסט המלא של הדקות הראשונות בהרצאה «Recycler View - Click Registrations» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אחרי שהצלחנו להציג רשימת פריטים בעזרת PreCycler View בואו נראה איך אנחנו יכולים לכתוב קוד כתגובה ללחיצה על פריט ברשימה. כאשר אנחנו עבדנו עם List View כל מה שהיינו צריכים לעשות זה להירשם לאיזשהו אירוע שנקרא Set on Item Click Listener וברגע שהיוזר לחץ על פריט ברשימה אוטומטית האירוע הזה התבצע ויכלנו לתפוס אותו ולכתוב בתוכו קוד.
אבל גם כאן הייתה בעיה עם ה-List View שנפתרת על ידי ה-Recycler View באופן טבעי והבעיה עם האירוע הזה הוא שלפעמים אנחנו רוצים לא רק לקבל אינדיקציה שהיוזר לחץ על פריט אלא אנחנו רוצים לדעת על מה בדיוק הוא לחץ בפריט עצמו כי כזכור פריט יכול להציג כל מיני רכיבי תצוגה שונים לדוגמת תמונה לדוגמת טקסט אז יכול להיות שאנחנו נרצה לדעת רגע היוזר
לחץ על התמונה או שהוא לחץ על הטקסט ולפי זה לבצע דברים אחרים. כאשר אנחנו עבדנו עם האירוע set on item click listener אז לא ידענו על מה היוזר בדיוק לחץ.
כאן ב-recycler view אין אירוע כזה ושיטת העבודה היא טיפה שונה. שיטת העבודה בשביל לדעת על מה בדיוק היוזר לחץ ובכלל שהוא לחץ על איזשהו פריט זאת שיטת העבודה שראינו בעבר עם כל הנושא של הליסנר אז בואו נראה איך אנחנו יכולים להטמיע גם כאן את הקונספט של הליסנר בכדי לגלות על מה בדיוק היוזר לחץ ברשימת הפריטים ועל כל פריט שהוא לחץ בדיוק על מה הוא לחץ
בפריט עצמו. הדבר הראשון שאנחנו מתחילים זה עם ההולדר אנחנו צריכים להיכנס להולדר ובהולדר אנחנו צריכים להבין שכאן יש לנו את הרכיבים הוויזואליים.
הנה אנחנו רואים את התמונה בדוגמה שעשינו, הנה אנחנו רואים את הטקסט view של ה-color, הטקסט view של ה-Karat, וה-view הזה בעצם מחזיק לנו את ה-Layout עצמו.
אז יש לנו ארבעה רכיבים שהיוזר יכול ללחוץ עליהם, על ה-Background, כלומר על ה-Layout, על התמונה, על הטקסט של ה-Color ועל הטקסט של ה-Karat.
אנחנו צריכים פשוט לגרום לדיווח של הלחיצה עצמה וזה מתבצע על ידי הליסנר דיזיין פאטרן. אז בואו נזכר איך בדיוק עושים את זה ונגלם את זה בדוגמא הזאת. הדבר הראשון שאנחנו צריכים להגדיר בתוך ה-diamond holder זה בעצם את האינטרפייס.
אז בואו נבנה פה public interface נקרא לו on-diamond-click-listener. בתוך האינטרפייס הזה נגדיר פונקציות שיתארו בדיוק על מה היוזר לחץ. לדוגמה onColorClick ואם היוזר לחץ על הטקסט של ה-Color בואו נדווח את ה-Color שנלחץ.
נגדיר את זה אפילו כ-ColorName שם הצבע שנלחץ. אוקיי אם היוזר לחץ על ה-KaratClick אז בואו נדווח את ה-Karat עצמו. קראת.
אם היוזר לחץ על התמונה onImageClick בואו נדווח את ה-ImageID שלה ואם היוזר לחץ על הרקע עצמו של הפריט לא בדיוק על רכיב ספציפי בואו נקרא לזה onBackgroundClick אז בואו נשלח במקרה הזה את כל ה-Diamond שנלחץ, פריט עצמו.
אחרי שיש לנו את ה-interface הזה הדבר הבא שאנחנו צריכים לעשות זה להעלות את האירוע בלחיצה. אז קודם כל אנחנו צריכים לגשת לאזור הגלובלי וליצור לנו private object מסוג onDiamondClickListen בואו נקרא לו listener ואנחנו רוצים איזושהי פונקציה שתאפשר להכניס מידע לליסטנר הזה.
אז בואו נבנה כאן public void set onDiamondClickListen פונקציה שתקבל on-diamond-click-listener ותכניס אותו לתוך ה-data-member-listener שהגדרנו למעלה.
כאן אנחנו מאפשרים למתכנת אחר לבוא ולהגיד לנו בבקשה הנה איזשהו אובייקט שמממש את האינטרפייס הזה ואני רוצה בעצם לקבל את הדיווחים אז אני נותן לכם את האובייקט הזה ועכשיו נא לדווח לי ברגע שיעשו קליקים שונים.
אז יש לנו כאן את הפרייבט הזה, יש לנו כאן את הפונקציה שתאפשר לרשום אותו וכל מה שאנחנו צריכים לעשות זה בקונסטרקטור לבוא ולהירשם לכל הרכיבים השונים.
אז בואו נתחיל עם ה-Item View. ה-Item View זה בעצם ה-Layout עצמו של כל אחד מהפריטים, זה ה-Layout של ה-Item Diamond. מה שאנחנו רוצים לעשות זה להירשם לאירוע Set on click listener רגיל New on click listener ואנחנו יודעים שהאירוע הזה יתבצע כאשר היוזר ילחץ קליק על ה-Layout של פריט כלשהו ברגע שהוא לוחץ קליק על ה-Layout של פריט כלשהו אז הפונקציה הזאת שכרגע הולכת
להיבנה מתבצעת וכל מה שאני רוצה לעשות בתוכה זה לדווח על ידי ה-Listener שלנו שנלחץ קליק אז כל מה שאנחנו צריכים לעשות זה listener.onBackgroundClick זאת הפונקציה שבנינו ואנחנו צריכים לשלוח אליה את הדיימונד מאיפה יש לי בדיוק את הדיימונד כאשר מוצג דיימונד חדש בהתאם לדוגמה שבנינו בסרטון הקודם אז יש לנו כאן את הפונקציה bindDiamond שמקבלת את האובייקט ומציגה
אותו על הרכיבים הוויזואליים השונים מה שאנחנו רוצים לעשות זה לשמור אותו פה באזור הגלובלי הנה הדיימונד שלנו והדיימונד הנוכחי שמוצג בואו ניקח ונגדיר אותו כאן this diamond שווה לדיימונד שמתקבל ויש לנו עכשיו את הדיימונד עצמו אבל כדאי שנעשה עוד בדיקה אחת לפני זה האם listener לא שווה ל null למה אנחנו צריכים לבצע את הבדיקה הזאת
מפני שאנחנו לא יודעים כאשר אנחנו בונים את הרכיב הזה האם באמת אותו מתכנת שמשתמש עם הרכיב שלנו באמת מעוניין לקבל את הדיווחים האלה.
אולי מתכנת אחר בחברה רוצה להציג את היהלומים ולא מעניין אותו לראות לחיצות או לבצע קוד כתגובה ללחיצות של היוזר. רק הצגת מידע נטו.
אז אם הוא לא ירצה להירשם לאירועים הוא פשוט לא יקרא לפונקציה הזאת, לא יביא לנו listener ואין לנו כאן listener כלומר יהיה פה איזשהו null ואסור לנו להשתמש בפונקציות אם יש פה null.
ולכן כל הזמן באירועים אנחנו חייבים לבדוק האם באמת זה שונה מנהל, אם כן מישהו נרשם ורוצה לקבל את הדיווחים ורק אז אני מבצע את הדיווחים עצמם.
זה משהו מאוד מאוד מקובל לביצוע. עכשיו אנחנו צריכים לבצע בעצם את אותו הדבר עבור כל אחד מהרכיבים הוויזואליים. אז למעשה אפשר אפילו לעשות איזשהו copy paste כזה, בואו נעתיק את זה ונדביק אותו 1, 2, 3 פעמים, וניקח את התמונה, ניקח את הטקסט view color, ממש אנחנו צריכים לעשות את זה אחד אחד,
ניקח את הטקסט view carat, לכל אחד אנחנו נרשמים, אבל לכל אחד אנחנו מעלים פונקציה אחרת, לדוגמה בתמונה אנחנו רוצים לקרוא ל-listener.on image click, פה אנחנו צריכים לשלוח את ה-image ID, כבר אנחנו נשיג את ה-image ID.
כאן אנחנו רוצים לקרוא ל-on-color-click ולשלוח את ה-color name. כאן אנחנו רוצים לקרוא ל-on-carat-click ולשלוח את ה-carat.
זאת אומרת, נרשמנו בעצמנו לאירועי קליק של הרכיבים הוויזואליים שנמצאים בתוך כל פריט שמציג יהלום, רקע, תמונה, color ו-carat, ברגע שלוחצים על המקליק אנחנו מדווחים את העובדה הזאת החוצה.
תכף אנחנו נירשם ונקבל את הדיווחים האלה. אז את הדיימונד דיווחנו בלחיצה על הרקע ובתמונה בעצם אנחנו צריכים לדווח את ה-ID שלה, כאן את ה-Color וכאן את ה-Karat.
אז Color ו-Karat זה לא קווי בעיה בואו ניקח דיימונד נקודה גט קולור ופה דיימונד גט קרט וזה פחות בעייתי. כאן אנחנו צריכים לקבל את ה-ID של התמונה בהתאם לאפיון שעשינו ויש לנו כבר איזושהי פונקציה או בעצם קטע קוד כאן אנחנו רואים אותו שאם יש לנו את השם של התמונה אנחנו יכולים דרכו לקבל את ה-ID.
אז מה שנעשה בשביל לחסוך בקוד בואו נעשה פה איזושהי פונקציית פרייבט אינט גט אימג' איידי פרום אימג' ניים כזאת שתקבל את האימג' ניים וכל מה שאנחנו רוצים לעשות זה להחזיר את הקונטקסט get resources get identifier אימג' ניים בואו פה נמיר ללואור קייס ואנחנו רוצים לחפש את זה בתיקיית drawable ואנחנו רוצים לקחת את ה package name הנה הוא פה בואו ניקח אותו נשים אותו
כאן basically אותו קוד שעשינו מקודם אנחנו פשוט מרימים אותו החוצה בשביל לא לחזור על קוד פעמיים ואז כאן אנחנו פשוט יכולים לקרוא לפונקציה get image id from image name בואו נעתיק אותה נדביק אותה פה נשלח לפונקציה הזאת את diamond get color זאת הפונקציה שאנחנו רוצים ואנחנו רוצים לשרשר את זה עם underline diamond ושרשר פלוס ואז
יש לנו בדיוק את ה-image name שאנחנו שולחים, הופכים אותו כאן אנחנו שולחים בעצם את ה-image name ואז חסכנו את השורה הזאת והזאת בואו נוציא את זה ועכשיו אנחנו יכולים ממש עם זה להשתמש בשביל לקבל את image name אוקיי בואו נבצע פה קצת משהו קצת אחר במקום image name color name זה יהיה קצת
יותר הגיוני ואז נוכל את השרשור הזה לעשות פה להיפטר ממנו כאן יש לנו color name את כל זה עכשיו אנחנו יכולים לקחת ופשוט לשים אותו פה. מה בעצם אמרנו הנה השם של הצבע white green pink whatever ואנחנו שולחים אותו לפונקציה הפונקציה תביא לנו את ה-id של התמונה ואנחנו שולחים את זה הלאה החוצה.