
ScrollView עם TextView תופס חצי מהמסך (גובה 0dp ו-weight שווה 1) ומתחתיו ImageView שתופס את החצי השני. את הטקסט והתמונה (דג זהב) טוענים דינמית בקוד בלחיצה על ה-TextView, כי נתונים שמגיעים מה-XML היו חוזרים אוטומטית ולא היינו רואים את הבעיה.layout-land. משנים בו את ה-LinearLayout להוריזונטלי ואת הרכיבים לרוחב 0dp וגובה match_parent, כך שהטקסט והתמונה זה לצד זה.protected. היא מורצת רגע לפני ההרס ומקבלת Bundle בשם outState, שהוא אוסף של זוגות מפתח וערך. שומרים בו את הטקסט בעזרת putString, את צבע הטקסט (getCurrentTextColor) בעזרת putInt, ואת התמונה כ-Bitmap בעזרת putParcelable.ImageView, כי הוא לא נשמר שם. לכן ממירים את ה-Drawable ל-BitmapDrawable ושולפים ממנו את ה-Bitmap, ושומרים null אם עדיין לא הוגדרה תמונה.protected. היא מורצת מיד אחרי שינוי הכיוון. שולפים בעזרת getString, getInt ו-getParcelable לפי אותם מפתחות, ומחזירים ל-setText, ל-setTextColor ול-setImageBitmap.Bundle שמתקבל גם ב-onCreate הוא אותו State שנשמר. אפשר לשחזר גם שם, אבל רק אחרי בדיקה שהוא לא null, שכן בהפעלה ראשונה הוא ריק.onCreate אינו שחזור מצבים קודמים.הטקסט המלא של הדקות הראשונות בהרצאה «Save Activity State» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
הפתרון השלישי שאנחנו הולכים לראות עבור שמירת הסטייט של האקטיביטי בזמן שינוי האוריינטיישן מתאים כאשר יש לנו שני לייאוטים ואנחנו כן רוצים שהאקטיביטי תהרס ותיווצר מחדש בכדי להחליף את הלייאוט בזמן שינוי האוריינטיישן אז בואו נראה איך אנחנו מתמודדים עם הדבר הזה קודם כל אנחנו רוצים שיהיה לנו שני לייאוטס
ואנחנו הולכים לבנות איזה משהו דומה למה שבנינו כבר בעבר עם שני הלייאוטס. מה שאנחנו הולכים לעשות זה תמונה וטקסט, כאשר הטקסט נמצא פה למעלה והתמונה מתחתיו וכאשר האקטיביטי נמצאת בלנסקייפ הטקסט נמצא משמאל והתמונה מימין אז בואו נבנה את הלייאוט הראשון שהוא עבור פורטרייט.
מה שאנחנו רוצים לעשות זה קודם כל אובייקט סקרול view, ניתן לו match parent אבל אנחנו רוצים שהheight שלו בפורטרייט יהיה 0 dp למה כי אנחנו רוצים לתת לו גם weight 1 בכדי שהוא יתפוס לנו בדיוק חצי מהמרווח ומתחתיו שתהיה לנו image view גם כן רוחב היא תתפוס לנו את הכל וגובה 0 dp ו-weight 1 ואז כל
אחד תופס בדיוק חצי ה-scroll view תופס את החצי העליון, התמונה תופסת את החצי התחתון ואנחנו רוצים לתת כאן ב-scroll view את scroll bars vertical שהיוזר יוכל לגלול בתוכו טקסט view, match parent, wrap content שיתפוס בדיוק כמה שהוא צריך, איזשהו ID,
ניתן לו טקסט בואו ניתן לו טקסט סייז של 25 SP ודבר נוסף שאנחנו רוצים לעשות בדוגמה הזאת שהוא קצת שונה מהדוגמה הקודמת ושאנחנו רוצים שהמידע יטען בצורה דינמית דרך Java Code.
למה? כי אם המידע נמצא כסטטי אז אנחנו לא נראה בעצם את ההריסה של המידע בשינוי האוריינטציה כי אם היוזר משנה את האוריינטציה ואנדרואי טוענת מחדש את הלאוט ויש הגדרות דיפולטיות בלאוט אז אנחנו מיידית נראה את ההגדרות האלה.
אבל אם אנחנו טוענים את ההגדרות האלה דינמית והן לא נמצאות כחלק מהxml אז כמובן הן ייעלמו ואנחנו כן רוצים לראות שההגדרות נעלמות ואנחנו משחזרים אותן.
לכן את כל ההגדרות של הטקסט ושל התמונה אנחנו רוצים לתת בצורה דינמית. אז מה שנרשום כאן זה נרשום click to view animal, איזשהו animal ואנחנו בעצם נציג את הגולדפיש שהצגנו אותו בעבר אבל רק בצורה דינמית.
יש לנו כאן on click, יש לנו text view animal, שבו אנחנו הולכים להכניס בצורה דינמית גם את הטקסט וגם את התמונה. בואו נחזור רגע, נעשה פה קצת סדר, אנחנו רוצים לתת ID גם לתמונה, אימג' ויו אנימל בצורה כזאת ונראה לי שסיימנו עם הלאוט הראשון של הפורטרייט בואו ניגש למיין
אקטיביטי ומה שאנחנו רוצים לעשות זה להגדיר את הרכיבים הוויזואליים יש לנו פרייבט טקסט ויו אנימל יש לנו אימג' ויו אנימל נאתר אותם טקסט view animal שווה text view, find view by id, r.id, text view animal, image view animal, נכניס את ה-image view, find view by id,
הנה יש לנו את ה-image view animal, ומה שאנחנו רוצים לעשות בלחיצה על הטקסט, בקליק של הטקסט, זה לגשת ל-text view animal ו-to set text, ויש לנו בתוך r-string coldfish ובעצם מדמה לנו מידע דינמי שאנחנו מביאים לא משנה מאיפה זה יכול להיות מקובץ ה-strings.xml זה יכול להיות שהורדנו אותו כרגע מהאינטרנט זה יכול להיות שהיוזר הכניס לנו אותו הוא בצורה דינמית
נכנס לתוך ה-text view. נבצע גם שינוי צבע, set text-color ל-color.blue ונגדיר את התמונה, image-view animal.set-image-resource ויש לנו בתוך r-drawable את גולדפיש שאנחנו רוצים להכניס.
דבר ראשון בואו נבדוק ונראה איך התוכנית מתנהגת כאשר אין לנו שני layout, יש לנו layout אחד ואז נוסיף עוד layout ונבדוק שוב.
בואו נריץ, הנה התוכנית רצה על המכשיר האמיתי, הנה התוכנית רצה על האמולטור, ניקח את המכשיר האמיתי וקודם כל נבצע איזשהו קליק ונראה שכל המידע מוצב לנו כמו שצריך, אבל אם אנחנו משנים את האוריינטציה אז קודם כל הכל נעלם, זה דבר ראשון כי לא טיפלנו במצב שאנחנו רוצים לשחזר את המידע, לא מנענו את היצירה של האקטיביטי מחדש, את ההריסה ואת היצירה וכמובן לא קיבענו
את האוריינטציה, אנחנו לא רוצים לעשות את זה. ואם אני לוחץ אז אנחנו רואים בצורה כזאת את הגרפיקה, טקסט מעל, תמונה למטה, מפני שעדיין לא שילבנו עוד layout בשביל להכיל את המידע אחד ליד השני. בואו נחזיר את זה לפורטרייט ונעלם, נלחץ, נראה את זה שוב.
עוד דבר אנחנו יכולים לראות במכשיר הנה המידע בואו נשנה את האוריינטציה הכל נעלם הנה המידע בצורה כזאת שאנחנו גם לא רוצים לראות אותו ככה נחזיר את זה ואנחנו צריכים כמובן לטפל בכל הסיטואציה הזאת אז הטיפול הראשון יהיה להוסיף עוד layout אז בואו ניגש נראה את ה-layout
שלנו ניגש לכאן ונגדיר לו create landscape version וראינו בעבר שהדבר הזה גם משכפל לנו את כל ה-layout לעוד קובץ layout שהוא זהה לחלוטין כרגע אבל הוא נמצא בתיקיית layout מקף land בכדי להיכנס לתוקף כאשר היוזר נמצא ב-landscape.
אנחנו עכשיו רוצים לעשות פה את השינויים הדרושים קודם כל ה-linear layout לא אמור להיות vertical הוא אמור להיות הוריזונטל ולכן את זה אנחנו מורידים, ה-Default תהיה הוריזונטל.
לאחר מכן אנחנו רוצים שה-Weed שלנו יהיה 0DP וה-High תהיה Match Parent. גם כאן אנחנו רוצים שה-Weed יהיה 0DP וה-High תהיה Match Parent וזה כבר מסדר אותם שמאל וימין ולמעשה אלו כל השינויים שאנחנו רוצים לבצע ב-Layout.
בואו נריץ ונראה איך זה מתנהג עכשיו. הנה התוכנית רצה על המכשיר האמיתי והנה התוכנית רצה על האמולטור. בואו ניגש למכשיר האמיתי, נלחץ ונראה את המידע מתייצב אחד מעל השני כי אנחנו בפורטרייט ואני מסובב את המכשיר ולוחץ שוב פעם והמידע מסתדר משמאל לימין הכל בסדר רק המידע נעלם בזמן שינוי האוריינטציה זה ברור.
לחצתי פה עוד פעם אנחנו רואים שהמידע נעלם אני לוחץ ורק אז הוא מופיע. אוקיי בואו ניגש לאמולטור אותו סיפור הנה אנחנו רואים את המידע אני מסובב המידע נעלם אז נכון שהוא מוצב כמו שצריך בחזרה כאשר אנחנו עוד פעם לוחצים אבל אנחנו לא רוצים ללחוץ עוד פעם אנחנו רוצים שכשהיוזר יסובב אוטומטית המידע יחזור אז קודם כל למה אנחנו לא יכולים
להשתמש בשני הפתרונות האחרונים שראינו שני הפתרונות הקודמים בגלל שאנחנו כן רוצים שבזמן שינוי האוריינטיישן האקטיביטי תיהרס ותיווצר מחדש בכדי להכיל את ה-Layout הנכון בהתאם לאוריינטציה או Portrait או Landscape.
עכשיו איך אנחנו פותרים את הבעיה שהמידע נעלם? קיימת פונקציה שנקראת OnSaveInstanceState אנחנו רוצים את הגרסה של ה-Protected שלה והפונקציה הזאת מתבצעת שנייה לפני שכל המידע נהרס מהאקטיביטי ברגע שאנחנו משנים את האוריינטציה.
וקיימת פונקציה נוספת שנקראת onRestoreInstanceState והפונקציה הזאת מתבצעת ממש אחרי שהאוריינטציה משתנה והסתיימה לגמרי בשביל שאנחנו נשחזר את הפרטים.
גם כאן אנחנו רוצים את הגרסה של ה-protected ולא של ה-public. אז בואו רגע נעיף את הדירקטיבז האלה, למעשה אין לנו צורך בסופר הזה, אנחנו פשוט רוצים רק לשמור את ה-state עצמו.
אז מה אנחנו רוצים לעשות? ברגע שהאוריינטציה משתנה, שנייה לפני שהאקטיביטי נהרסת ושנייה לפני שאנחנו מאבדים את כל המידע, יש לנו צ'אנס אחרון לשמור בעצמנו את הנתונים.
ומה שאנחנו מקבלים לפונקציה זה משתנה מסוג bundle, Wandel זה פשוט חבילה שמכילה Key-Value Collection כלומר איזשהו קולקשן שיש בו Key-Value Pairs זוגות זוגות של Key-Value יש לנו את המשתנה שנקרא Outstate וכל מה שאנחנו צריכים לעשות זה פשוט להכניס לתוכו נתונים.
כל נתון שאנחנו מכניסים יש לנתון גם מפתח וגם את הנתון עצמו בכדי שאחר כך נוכל לשלוף את הנתון לפי המפתח ואנחנו יכולים לשמור איזה נתונים שבא לנו.
אז יש לנו פה כל מיני פונקציות put, putString, putInteger, putBullion, מה שבא