
SurfaceView עם match_parent לרוחב ולגובה, ו-ID, ומאתרים אותו ב-MainActivity עם findViewById. אפשר להציג בו מצלמה, וידאו, תמונות ועוד.getHolder() של ה-SurfaceView מחזיר רכיב פנימי שהוא מקום התצוגה. נותנים אותו לרכיב שמציג (כאן המצלמה, ובהמשך אפשר וידאו) והוא משדר לתוכו, ואנחנו רואים את זה ב-SurfaceView.addCallback עם האקטיביטי עצמו, שמממש את SurfaceHolder.Callback. יש שלוש פונקציות: surfaceCreated, surfaceChanged ו-surfaceDestroyed.Camera.open(0) (האינדקס מזהה מצלמה, למשל קדמית או אחורית), קוראים ל-setPreviewDisplay עם ה-holder ואז ל-startPreview. הקריאה ל-setPreviewDisplay צריכה להיות בתוך try/catch ובשגיאה מציגים Toast.release, למשל כשהמשתמש עבר לאפליקציה אחרת. ב-surfaceChanged לא עושים כלום כרגע.WRITE_EXTERNAL_STORAGE כבר קיימת, לשמירת התמונה בהמשך.setDisplayOrientation(90).הטקסט המלא של הדקות הראשונות בהרצאה «מצלמה - חלק 3 - צילום מתוך האפליקציה» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
בסרטונים הקודמים הצלחנו לצלם תמונה ולשמור אותה, אבל עשינו את זה על ידי שימוש באפליקציית הקאמרה שקיימת במכשיר. זאת אומרת שבכדי להצליח לצלם תמונה היינו צריכים לעבור מהאפליקציה שלנו לאפליקציית הקאמרה, לבצע את הצילום ואז לחזור לאפליקציה שלנו אחרי שצילמנו את הצילום ואולי לראות את התמונה
ולשמור אותה. אבל מה קורה אם אנחנו לא רוצים לעבור לאפליקציית הקאמרה ובכלל לא רוצים להשתמש באפליקציית הקאמרה, אלא אנחנו רוצים לא לצאת בכלל מהאפליקציה שלנו ולהראות באפליקציה שלנו כאילו קאמרה ולאפשר לצלם תמונה וגם לשמור אותה מתוך האפליקציה שלנו.
אז לצורך כך אנחנו יכולים להשתמש ברכיב מעניין שקיים באנדרואיד והוא נקרא Surface View. Service View מאפשר להציג את הקאמרה, מאפשר להציג וידאו, מאפשר להציג תמונות ועוד ואנחנו הולכים לראות בסרטון הזה איך אנחנו יכולים להשתמש ב-surface view בכדי להציג קאמרה בתוך האפליקציה שלנו
ובהמשך כמובן להשתמש ב-surface view בשביל לצלם את התמונה אז כל מה שאנחנו צריכים לעשות זה פשוט להציג ב-layout שלנו רכיב מטיפוס surface view בואו נגדיר אותו כ-match parent בואו ניתן לו איזשהו ID נקרא לו Surface View Camera כעת אנחנו יכולים פשוט לגשת למיין אקטיביטי לאתר את הרכיב בואו נגדיר פה פרייבט Surface View הנה הוא כאן וה-ID שלו בואו נאתר אותו
Surface View, Find View by ID ו-RID Surface View Camera, והנה קודם כל יש לנו גישה לרכיב הזה מה-Java Code. הדבר הבא שאנחנו צריכים לעשות זה להגדיר אובייקט שנקרא Surface Holder.
ה-Surface Holder זה רכיב שבעצם בתוכו אנחנו מציגים את המידע שאנחנו רוצים. אפשר להתייחס אליו כאילו שהוא איזשהו קומפוננטה פנימית בתוך ה-Surface View.
איך כל הסיפור הזה עובד? ה-Surface View צריך להביא לנו את הרכיב הפנימי שלו הזה, ה-Surface Holder, ואנחנו צריכים לתת את ה-Surface Holder לאותו רכיב שרוצה להציג את התצוגה.
לדוגמה, לקאמרה. אם אנחנו נותנים לקאמרה בעזרת פונקציה מיוחדת את ה-Surface Holder, אז הקאמרה מציגה את עצמה בתוך ה-Surface Holder וזה ייראה בתוך ה-Surface View.
אם אנחנו לדוגמה רוצים להציג וידאו, אז אנחנו צריכים לתת את ה-Surface Holder הזה לאיזשהו רכיב וידאו, ואז רכיב הוידאו ישדר את עצמו לתוך ה-Surface Holder, וכמובן אנחנו נראה את זה בתוך ה-Surface View, מפני שה-Surface View מביא לנו את ה-Surface Holder,
הרכיב הפנימי הזה שלו אז בואו נראה איך אנחנו עושים את זה אז יש לנו פה את ה-Surface Holder ואנחנו רוצים לגשת ל-Surface View Camera שהשגנו ולגשת לפונקציה שנקראת Get Holder.
פונקציית Get Holder מחזירה לנו את הרכיב הפנימי הזה שלו וכעת אנחנו יכולים לתת אותו לאיזשהו רכיב קאמרה או וידאו בהקשר הזה לקאמרה והיא תציג את עצמה בתוך ה-Surface Holder הזה ואנחנו כמובן, נראה את זה ב-Layout שלנו בתוך ה-Surface View שהגדרנו.
אז איך בעצם אנחנו גורמים לזה להתבצע? אנחנו מגדירים באזור הגלובלי אובייקט מטיפוס קאמרה. אז בואו ניקח את אובייקט הקאמרה, אנחנו רואים שהוא מאנדרואיד Hardware בצורה כזאת, וכעת מה שאנחנו רוצים לעשות זה להגדיר מעין אינטרפייס מיוחד, שימוש באינטרפייס מיוחד, ומבצע אתחול של כל ה-Holder.
אנחנו באים ל-Surface Holder וקוראים לפונקציה שנקראת Add Callback. הפונקציה הזאת מקבלת אינטרפייס Callback. בואו ניתן את This, נלחץ Alt Enter, נגדיר שאנחנו רוצים שה-Main Activity שלנו תממש את האינטרפייס הזה עם שלושת הפונקציות שבו, והנה יש לנו את זה כאן,
SurfaceHolder.Callback, והפונקציות האלה זה פונקציות שמתרחשות כאשר ה-surface holder מבצע אתחול, שינוי והריסה. ואנחנו צריכים להתאים את המצלמה ל-holder בתוך ה-surface created.
בתוך האירוע ה-surface created, ברגע שה-surface נוצר, איך שעליה עוד נוצר איתו ביחד, אז אירוע ה-surface created מתבצע ואנחנו בו רוצים להגדיר את המצלמה ולחבר אותה עם ההולדר שלנו.
אז בתוך אירוע ה-surface created בואו ניגש לאובייקט הקאמרה שלנו הגלובלי ונכניס לתוכו camera.open פונקציה שפשוט פותחת את המצלמה, אנחנו יכולים לקרוא ל-open בצורה כזאת והיא הולכת למצלמת הדיפולט או לתת לה איזשהו ID של מצלמה אם יש מספר מצלמות.
בואו ניקח ID 0, יכול להיות שיש לנו פרונט קאמרה ובאק קאמרה ואנחנו רוצים איזשהו אינדקס ספציפי של המצלמה. והדבר הבא שאנחנו פשוט רוצים לעשות זה camera.setpreview.display ולתת את אובייקט ההולדר שלנו.
בואו ניתן את ה-surface holder בכדי שאובייקט המצלמה ידע בדיוק איפה לשדר את המצלמה וזה כמובן בהולדר שלנו. ואנחנו רואים שהמערכת רוצה שנעטוף את זה ב-try