‫Android Kotlin Fundamentals 01.2: Basic app anatomy

ה-codelab הזה הוא חלק מהקורס Android Kotlin Fundamentals. כדי להפיק את המרב מהקורס הזה, מומלץ לעבוד על ה-codelabs לפי הסדר. כל ה-codelab של הקורס מפורטים בדף הנחיתה של ה-codelab בנושא יסודות Kotlin ל-Android.

מבוא

עד עכשיו הגדרתם הכול, ו-Android Studio יצר בשבילכם הרבה קוד. לפני שמשנים את כל הקוד הזה, חשוב להבין מה יצרתם ואיך לנווט בקובצי המקור של אפליקציית Android.

ב-codelab הזה תלמדו על הרכיבים העיקריים של אפליקציית Android ותוסיפו לאפליקציה אינטראקטיביות פשוטה באמצעות לחצן.

מה שכדאי לדעת

  • איך מתקינים ופותחים את Android Studio.
  • איך יוצרים פרויקט חדש של אפליקציה.
  • איך מריצים אפליקציה באמולטור או במכשיר פיזי.

מה תלמדו

  • איך עורכים את קובץ הפריסה של האפליקציה.
  • איך יוצרים אפליקציה עם התנהגות אינטראקטיבית.
  • הרבה טרמינולוגיה חדשה. כדאי לעיין במילון המונחים כדי לקבל הסברים פשוטים על מונחים ומושגים.

מה עושים

  • מעיינים בקובץ MainActivity Kotlin ובקובץ הפריסה של הפעילות.
  • עריכת הפריסה של הפעילות ב-XML.
  • מוסיפים רכיב Button לפריסת הפעילות.
  • חילוץ מחרוזות שמוגדרות בהארדקוד לקובץ של משאבי מחרוזות.
  • מטמיעים שיטות לטיפול בלחיצות כדי להציג הודעות במסך כשהמשתמש מקיש על Button.

ב-codelab הזה, תיצרו פרויקט חדש של אפליקציה בשם DiceRoller ותוסיפו אינטראקטיביות בסיסית באמצעות לחצן. בכל פעם שלוחצים על הלחצן, הערך של הטקסט שמוצג משתנה. אפליקציית DiceRoller הסופית של ה-Codelab הזה נראית כך:

ב-codelab הקודם למדתם על החלקים העיקריים של פרויקט אפליקציה, כולל הספריות java ו-res. במשימה הזו מתמקדים בשני הקבצים הכי חשובים שמרכיבים את האפליקציה: קובץ MainActivity Kotlin וקובץ הפריסה activity_main.xml.

שלב 1: בודקים את MainActivity

MainActivity היא דוגמה ל-Activity. ‫Activity הוא מחלקה מרכזית ב-Android שמציירת את ממשק המשתמש של אפליקציית Android ומקבלת אירועי קלט. כשהאפליקציה מופעלת, היא מפעילה את הפעילות שצוינה בקובץ AndroidManifest.xml.

בהרבה שפות תכנות מוגדרת שיטה ראשית שמפעילה את התוכנית. לאפליקציות ל-Android אין שיטה ראשית. במקום זאת, הקובץ AndroidManifest.xml מציין שצריך להפעיל את MainActivity כשהמשתמש מקיש על סמל ההפעלה של האפליקציה. כדי להפעיל פעילות, מערכת ההפעלה Android משתמשת במידע במניפסט כדי להגדיר את הסביבה של האפליקציה וליצור את MainActivity. אחר כך MainActivity מבצע הגדרה כלשהי.

לכל פעילות יש קובץ פריסה משויך. הפעילות והפריסה מקושרות באמצעות תהליך שנקרא פריסת פריסה. כשהפעילות מתחילה, התצוגות שמוגדרות בקובצי הפריסה של ה-XML הופכות לאובייקטים של תצוגות Kotlin בזיכרון (או שהן עוברות 'ניפוח' לאובייקטים כאלה). אחרי שזה קורה, הפעילות יכולה לצייר את האובייקטים האלה על המסך וגם לשנות אותם באופן דינמי.

  1. ב-Android Studio, בוחרים באפשרות File > New > New Project (קובץ > חדש > פרויקט חדש) כדי ליצור פרויקט חדש. משתמשים בפעילות ריקה ולוחצים על הבא.
  2. קוראים לפרויקט DiceRoller, ומאמתים את כל שאר הערכים של שם הפרויקט ומיקום הפרויקט. מוודאים שהתיבה 'שימוש בארטיפקטים של AndroidX' מסומנת. לוחצים על סיום.


  3. בחלונית Project > Android, מרחיבים את java > com.example.android.diceroller. לוחצים לחיצה כפולה על MainActivity. הקוד מוצג בעורך הקוד ב-MainActivity.


  4. מתחת לשם החבילה ולהצהרות הייבוא מופיעה הצהרת המחלקה של MainActivity. הכיתה MainActivity class extends AppCompatActivity.
class MainActivity : AppCompatActivity() { ...
  1. שימו לב ל-method‏ onCreate(). פעילויות לא משתמשות בבונה כדי לאתחל את האובייקט. במקום זאת, מתבצעת קריאה לסדרה של שיטות מוגדרות מראש (שנקראות 'שיטות מחזור חיים') כחלק מהגדרת הפעילות. אחת מהשיטות האלה של מחזור החיים היא onCreate(), שתמיד מבטלים את ברירת המחדל שלה באפליקציה שלכם. מידע נוסף על שיטות מחזור החיים מופיע בהמשך במעבדת הקוד.

    ב-onCreate(), מציינים את הפריסה שמשויכת לפעילות, ומנפחים את הפריסה. השיטה setContentView() מבצעת את שתי הפעולות האלה.
override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)
}

השיטה setContentView() מפנה לפריסה באמצעות R.layout.activity_main, שהוא למעשה הפניה למספר שלם. הסיווג R נוצר כשמבצעים build לאפליקציה. הסיווג R כולל את כל הנכסים של האפליקציה, כולל התוכן של הספרייה res.

במקרה הזה, R.layout.activity_main מתייחס לכיתה R שנוצרה, לתיקייה layout ולקובץ הפריסה activity_main.xml. (המשאבים לא כוללים סיומות קבצים). תתייחסו לרבים מהמשאבים של האפליקציה (כולל תמונות, מחרוזות ואלמנטים בקובץ הפריסה) באמצעות הפניות דומות במחלקה R.

שלב 2: בודקים את קובץ הפריסה של האפליקציה

לכל הפעילויות באפליקציה יש קובץ פריסה משויך בספרייה res/layout של האפליקציה. קובץ פריסה הוא קובץ XML שמבטא איך פעילות נראית בפועל. קובץ פריסה עושה את זה על ידי הגדרת תצוגות והגדרת המיקום שבו התצוגות מופיעות במסך.

תצוגות הן רכיבים כמו טקסט, תמונות ולחצנים שמרחיבים את המחלקה View. יש הרבה סוגים של תצוגות, כולל TextView,‏ Button,‏ ImageView ו-CheckBox.

במשימה הזו תבדקו ותשנו את קובץ הפריסה של האפליקציה.

  1. בחלונית Project > Android (פרויקט > Android), מרחיבים את res > layout (משאבים > פריסה) ולוחצים פעמיים על activity_main.xml. העורך של עיצוב הפריסה ייפתח. ‫Android Studio כולל את העורך הזה, שמאפשר לכם ליצור את הפריסה של האפליקציה בצורה חזותית ולראות תצוגה מקדימה של עיצוב הפריסה. ב-codelab מאוחר יותר תוכלו לקרוא מידע נוסף על כלי העיצוב.
  2. כדי להציג את קובץ הפריסה כ-XML, לוחצים על הכרטיסייה Text (טקסט) בחלק התחתון של החלון.


  3. מוחקים את כל קוד ה-XML הקיים בכלי לעריכת פריסות. פריסת ברירת המחדל שמקבלים עם פרויקט חדש היא נקודת התחלה טובה אם עובדים עם כלי העיצוב של Android Studio. בשיעור הזה תעבדו עם קובץ ה-XML הבסיסי כדי לבנות פריסה חדשה מאפס.
  4. מעתיקים את הקוד הזה ומדביקים אותו בפריסה:
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout   
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

</LinearLayout>

עכשיו בודקים את הקוד:

  1. הרכיב ברמה העליונה או הבסיסית של הפריסה הוא רכיב <LinearLayout>. התצוגה LinearLayout היא ViewGroup. תצוגות קבוצתיות הן מאגרי נתונים שמכילים תצוגות אחרות ועוזרים לציין את המיקומים של התצוגות במסך.

    כל התצוגות וקבוצות התצוגות שמוסיפים לפריסה מאורגנות בהיררכיית תצוגות, כאשר רכיב ה-XML העליון ביותר הוא הבסיס של ההיררכיה הזו. תצוגת הבסיס יכולה להכיל תצוגות אחרות וקבוצות תצוגות, וקבוצות התצוגות שנכללות בה יכולות להכיל תצוגות אחרות וקבוצות תצוגות. כשהאפליקציה מפעילה את היררכיית התצוגה, היררכיית הפריסה בקובץ ה-XML הופכת להיררכיית אובייקטים כשהפריסה מורחבת. במקרה הזה, קבוצת התצוגה הבסיסית היא פריסה ליניארית, שמארגנת את תצוגות הצאצא שלה באופן ליניארי, אחת אחרי השנייה (במאונך או במאוזן).

    ה-root שמוגדר כברירת מחדל בפרויקט חדש ל-Android הוא ConstraintLayout, שפועל היטב בשילוב עם כלי העריכה של העיצוב. באפליקציה הזו, משתמשים בקבוצת תצוגה LinearLayout, שהיא פשוטה יותר מפריסת האילוצים. בשיעור הבא תקבלו מידע נוסף על קבוצות תצוגה ועל פריסת אילוצים.
  2. בתג LinearLayout, שימו לב למאפיין android:layout_width. הרוחב של LinearLayout מוגדר כ-match parent, ולכן הוא זהה לרוחב של רכיב האב. מכיוון שזו תצוגת הבסיס, הפריסה מתרחבת לרוחב המלא של המסך.
  3. שימו לב למאפיין android:layout_height, שהערך שלו מוגדר כ-wrap_content. המאפיין הזה גורם לגובה של LinearLayout להיות זהה לגובה המשולב של כל התצוגות שהוא מכיל, שכרגע הוא רק TextView.
  4. בודקים את הרכיב <TextView>. רכיב TextView, שמציג טקסט, הוא הרכיב החזותי היחיד באפליקציית DiceRoller. המאפיין android:text מכיל את המחרוזת שמוצגת בפועל, ובמקרה הזה המחרוזת "Hello World!"
  5. שימו לב למאפיינים android:layout_width ו-android:layout_height באלמנט <TextView>, ששניהם מוגדרים לערך wrap_content. התוכן של תצוגת הטקסט הוא הטקסט עצמו, ולכן התצוגה תתפוס רק את המקום שנדרש לטקסט.

אפליקציה לזריקת קובייה לא שימושית במיוחד אם אין למשתמש דרך לזרוק את הקובייה ולראות מה יצא. כדי להתחיל, מוסיפים פריסת לחצן להטלת קובייה ומוסיפים טקסט שמציג את הערך של הקובייה שהמשתמש הטיל.

שלב 1: מוסיפים לחצן לפריסה

  1. מוסיפים רכיב Button לפריסה מתחת לתצוגת הטקסט על ידי הקלדת <Button והקשה על Return. מופיע בלוק Button שמסתיים ב-/> וכולל את המאפיינים layout_width ו-layout_height.
<Button
   android:layout_width=""
   android:layout_height="" />
  1. מגדירים את המאפיינים layout_width ו-layout_height כ-"wrap_content". הערכים האלה קובעים שהרוחב והגובה של הכפתור יהיו זהים לרוחב ולגובה של תווית הטקסט שהוא מכיל.
  2. מוסיפים מאפיין android:text ללחצן ומקצים לו את הערך Roll. רכיב הלחצן נראה עכשיו כך:
<Button
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="Roll" />


For Button views the text attribute is the label of the button. בכלי לעריכת פריסות, המאפיין מודגש בצהוב, מה שמציין טיפ או אזהרה. במקרה הזה, ההדגשה בצהוב היא בגלל שהמחרוזת "Roll" מוצפנת בתווית של הלחצן, אבל המחרוזת צריכה להיות משאב. בקטע הבא מוסבר על משאבי מחרוזות.

שלב 2: חילוץ משאבי מחרוזות

במקום להגדיר מחרוזות בקשיחות בקובצי הפריסה או בקוד, מומלץ להכניס את כל המחרוזות של האפליקציה לקובץ נפרד. הקובץ הזה נקרא strings.xml והוא נמצא בין המשאבים של האפליקציה, בספרייה res/values/.

אם המחרוזות נמצאות בקובץ נפרד, קל יותר לנהל אותן, במיוחד אם משתמשים בהן יותר מפעם אחת. בנוסף, קובצי משאב למחרוזות הם חובה לתרגום ולהתאמה לשוק המקומי של האפליקציה, כי צריך ליצור קובץ משאב למחרוזות לכל שפה.

‫Android Studio עוזר לכם לזכור להוסיף את המחרוזות לקובץ משאבים באמצעות רמזים ואזהרות.

  1. לוחצים פעם אחת על המחרוזת Roll (תפקיד) במאפיין android:text של התג <Button>.
  2. לוחצים על Alt+Enter (או על Option+Enter ב-macOS) ובוחרים באפשרות Extract string resource (חילוץ משאב מחרוזת) בתפריט הקופץ.
  3. מזינים roll_label בשם המשאב.
  4. לוחצים על אישור. נוצר משאב מחרוזת בקובץ res/values/string.xml, והמחרוזת ברכיב Button מוחלפת בהפניה למשאב הזה:
    android:text="@string/roll_label"
  5. בחלונית Project > Android, מרחיבים את res > values, ואז לוחצים לחיצה כפולה על strings.xml כדי לראות את משאבי המחרוזות בקובץ strings.xml:
<resources>
   <string name="app_name">DiceRoller</string>
   <string name="roll_label">Roll</string>
</resources>

שלב 3: הגדרת הסגנון והמיקום של התצוגות

פריסת המסך כוללת עכשיו תצוגה אחת של TextView ותצוגה אחת של Button. במשימה הזו, אתם מסדרים את התצוגות בקבוצת התצוגות כך שהן ייראו מושכות יותר.

  1. לוחצים על הכרטיסייה עיצוב כדי לראות תצוגה מקדימה של הפריסה. בשלב הזה שני התצוגות מוצגות זו לצד זו בחלק העליון של המסך.


  2. לוחצים על הכרטיסייה טקסט כדי לחזור לעורך ה-XML. מוסיפים את המאפיין android:orientation לתג LinearLayout ומזינים בו את הערך "vertical". עכשיו הרכיב <LinearLayout> אמור להיראות כך:
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   tools:context=".MainActivity">

התצוגה LinearLayout view group ממקמת את התצוגות שהיא מכילה אחת אחרי השנייה בשורה, או אופקית בשורה או אנכית בערימה. ברירת המחדל היא אופקית. כדי שהצורה TextView תהיה מעל הצורה Button, מגדירים את הכיוון לאנכי. העיצוב ייראה עכשיו כך, עם הכפתור מתחת לטקסט:

  1. מוסיפים את מאפיין android:layout_gravity גם ל-TextView וגם ל-Button, ומזינים בו את הערך "center_horizontal". כך שתי התצוגות יתיישרו לאורך מרכז הציר האופקי. עכשיו האלמנטים TextView ו-Button אמורים להיראות כך:
<TextView   
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:text="Hello World!" />

<Button
   android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="@string/roll_label" />
  1. מוסיפים את המאפיין android:layout_gravity לפריסה הקווית ומקצים לו את הערך "center_vertical". עכשיו רכיב LinearLayout אמור להיראות כך:
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:orientation="vertical"
   android:layout_gravity="center_vertical"
   tools:context=".MainActivity">
  1. כדי להגדיל את גודל הטקסט בתצוגת הטקסט, מוסיפים את המאפיין android:textSize לרכיב <TextView> עם הערך "30sp". הקיצור sp מייצג פיקסלים שניתן לשנות, שזו יחידת מידה לקביעת גודל הטקסט בלי קשר לאיכות התצוגה של המכשיר. רכיב TextView אמור להיראות עכשיו כך:
<TextView   
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:textSize="30sp"
   android:text="Hello World!" />
  1. קומפילציה והרצה של האפליקציה.


עכשיו גם הטקסט וגם הכפתור ממוקמים בצורה טובה, והטקסט בתצוגת הטקסט גדול יותר. ללחצן עדיין אין פונקציונליות, ולכן לא קורה כלום כשלוחצים עליו. אחר כך תעבדו על זה.

שלב 4: מקבלים הפניה לכפתור בקוד

קוד Kotlin ב-MainActivity אחראי להגדרת החלקים האינטראקטיביים של האפליקציה, כמו מה קורה כשמקישים על לחצן. כדי לכתוב פונקציה שמופעלת כשלוחצים על הלחצן, צריך לקבל הפניה לאובייקט Button בפריסה המורחבת ב-MainActivity. כדי לקבל הפניה ללחצן:

  • מקצים ל-Button מזהה בקובץ ה-XML.
  • משתמשים בשיטה findViewById() בקוד כדי לקבל הפניה ל-View עם מזהה ספציפי.

אחרי שיש לכם הפניה לתצוגה Button, אתם יכולים להפעיל מתודות בתצוגה הזו כדי לשנות אותה באופן דינמי בזמן שהאפליקציה פועלת. לדוגמה, אפשר להוסיף handler של לחיצה שמריץ קוד כשמקישים על הלחצן.

  1. פותחים את קובץ הפריסה activity_main.xml, אם הוא עדיין לא פתוח, ולוחצים על הכרטיסייה Text (טקסט).
  2. מוסיפים את המאפיין android:id ללחצן ונותנים לו שם (במקרה הזה, @+id/roll_button"). עכשיו האלמנט <Button> נראה כך:
<Button
   android:id="@+id/roll_button"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:text="@string/roll_label" />

כשיוצרים מזהה לתצוגה בקובץ הפריסה של XML, ‏ Android Studio יוצר קבוע מסוג integer עם השם של המזהה הזה במחלקה R שנוצרת. לכן, אם נותנים לתצוגה את השם roll_button,‏ Android Studio יוצר קבוע מסוג integer בשם roll_button במחלקה R. הקידומת "@+id" לשם המזהה מציינת לקומפיילר להוסיף את קבוע המזהה הזה למחלקה R. כל מזהי התצוגות בקובץ ה-XML חייבים להתחיל בקידומת הזו.

  1. פותחים את קובץ ה-MainActivity Kotlin. בתוך onCreate(), אחרי setContentView(), מוסיפים את השורה הבאה:
val rollButton: Button = findViewById(R.id.roll_button)

משתמשים בשיטה findViewById() כדי לקבל הפניה ל-View לתצוגה שהגדרתם בכיתת ה-XML. במקרה הזה, מקבלים את ההפניה Button מהמחלקה R ואת המזהה roll_button, ומקצים את ההפניה למשתנה rollButton.

  1. שימו לב ש-Android Studio מדגיש את המחלקה Button באדום ומסמן אותה בקו תחתון, כדי לציין שמדובר בהפניה שלא נפתרה וצריך לייבא את המחלקה הזו כדי להשתמש בה. יכול להיות שיופיע גם תיאור קצר שמציין את שם המחלקה המלא:


  2. מקישים על Alt+Enter (או על Option+Enter ב-Mac) כדי לאשר את שם המחלקה המלא.

שלב 5: מוסיפים click handler כדי להציג טוסט

Click handler היא שיטה שמופעלת בכל פעם שהמשתמש לוחץ או מקיש על רכיב קליקבילי בממשק המשתמש, כמו לחצן. כדי ליצור click handler, צריך:

  • שיטה שמבצעת פעולה מסוימת.
  • השיטה setOnClickHandler(), שמקשרת את Button לשיטת הטיפול.

במשימה הזו תיצרו שיטה לטיפול בקליקים כדי להציג Toast. (חלון קופץ הוא הודעה שמופיעה במסך לזמן קצר). מקשרים את שיטת הטיפול בלחיצה אל Button.

  1. במחלקת MainActivity אחרי onCreate(), יוצרים פונקציה פרטית בשם rollDice().
private fun rollDice() {
  
}
  1. מוסיפים את השורה הזו לשיטה rollDice() כדי להציג את Toast כשקוראים ל-rollDice():
Toast.makeText(this, "button clicked", 
   Toast.LENGTH_SHORT).show()

כדי ליצור הודעה קצרה, קוראים ל-method‏ Toast.makeText(). השיטה הזו דורשת שלושה דברים:

  • אובייקט Context. אובייקט Context מאפשר לכם לתקשר עם מערכת Android OS ולקבל מידע על המצב הנוכחי שלה. כאן צריך להשתמש ב-Context כדי שאובייקט Toast יוכל להורות למערכת ההפעלה להציג את ההודעה הקופצת. מכיוון ש-AppCompatActivity הוא מחלקת משנה של Context, אפשר פשוט להשתמש במילת המפתח this להקשר.
  • ההודעה שתוצג, כאן "button clicked".
  • משך הזמן שבו ההודעה תוצג. השיטה show() בסוף מציגה את ההודעה הקצרה.
  1. ב-onCreate(), אחרי הקריאה ל-findViewById(), מוסיפים את השורה הזו כדי להקצות את rollDice() כמטפל בקליקים לאובייקט rollButton:
rollButton.setOnClickListener { rollDice() }

ההגדרה המלאה של המחלקה MainActivity נראית עכשיו כך:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val rollButton: Button = findViewById(R.id.roll_button)
        rollButton.setOnClickListener { rollDice() }
    }

    private fun rollDice() {
        Toast.makeText(this, "button clicked",
            Toast.LENGTH_SHORT).show()
    }
}
  1. קומפילציה והרצה של האפליקציה. בכל פעם שמקישים על הלחצן, אמורה להופיע הודעה קצרה.

במשימה הזו, משנים את הטקסט ב-TextView באמצעות שיטת rollDice(). בשלב הראשון, משנים את הטקסט מ-"Hello World!" למחרוזת "Dice Rolled!". בשלב השני, מוצג מספר אקראי בין 1 ל-6.

שלב 1: הצגת מחרוזת

  1. פותחים את activity_main.xml ומוסיפים מזהה ל-TextView.
android:id="@+id/result_text"
  1. פתיחת MainActivity. בשיטה rollDice(), מוסיפים הערה לשורה כדי להציג את Toast.
  2. משתמשים בשיטה findViewById() כדי לקבל הפניה אל TextView באמצעות המזהה שלו. מקצים את ההפניה למשתנה resultText.
val resultText: TextView = findViewById(R.id.result_text)
  1. כדי לשנות את הטקסט שמוצג, מקצים מחרוזת חדשה לנכס resultText.text. אפשר להתעלם מההנחיה לחלץ את המחרוזת הזו למשאב, כי זו רק מחרוזת זמנית.
resultText.text = "Dice Rolled!"
  1. קומפילציה והרצה של האפליקציה. שימו לב שהקשה על הלחצן Roll מעדכנת עכשיו את TextView.

שלב 2: הצגת מספר אקראי

לבסוף, במשימה הזו מוסיפים אקראיות ללחיצה על הלחצן, כדי לדמות הטלת קובייה. בכל פעם שלוחצים על הלחצן או מקישים עליו, הקוד בוחר מספר אקראי מ-1 עד 6 ומעדכן את TextView. המשימה של יצירת מספר אקראי לא ספציפית ל-Android, ואתם משתמשים במחלקה Random כדי לבצע אותה.

  1. בחלק העליון של ה-method ‏rollDice(), משתמשים ב-method ‏Random.nextInt() כדי לקבל מספר רנדומלי בין 1 ל-6:
val randomInt = Random().nextInt(6) + 1
  1. מגדירים את הנכס text לערך של המספר השלם האקראי, כמחרוזת:
resultText.text = randomInt.toString()
  1. קומפילציה והרצה של האפליקציה. בכל פעם שמקישים על הלחצן Roll, המספר בתצוגת הטקסט משתנה.

פרויקט Android Studio: ‏ DiceRoller

אתגר: מוסיפים לאפליקציה לחצן שני עם התווית Count Up (ספירה עולה) שמופיע ממש מתחת ללחצן Roll (הטלה). כשמקישים על הלחצן ספירה עולה, הערך הנוכחי של תצוגת הטקסט של התוצאה צריך להתעדכן, כלומר להוסיף לו 1. חשוב לטפל במקרים הקיצוניים האלה:

  • אם תצוגת הטקסט של התוצאה עדיין לא מכילה מספר (כלומר, אם בתצוגת הטקסט עדיין מופיעה מחרוזת ברירת המחדל Hello World), מגדירים את הטקסט של התוצאה ל-1.
  • אם המספר הוא כבר 6, לא צריך לעשות כלום.

קוד הפתרון של אתגר התכנות

פרויקט Android Studio: ‏ DiceRoller-challenge

פעילויות

  • MainActivity היא מחלקה משנית של AppCompatActivity, שהיא מחלקה משנית של Activity. ‫Activity הוא מחלקה מרכזית ב-Android שאחראית על שרטוט ממשק המשתמש של אפליקציית Android ועל קבלת אירועי קלט.
  • לכל פעילות משויך קובץ פריסה, שהוא קובץ XML במשאבים של האפליקציה. קובץ הפריסה נקרא על שם הפעילות, למשל activity_main.xml.
  • השיטה setContentView() ב-MainActivity משייכת את הפריסה לפעילות, ומנפחת את הפריסה הזו כשהפעילות נוצרת.
  • התהליך של יצירת פריסה הוא תהליך שבו התצוגות שמוגדרות בקובצי הפריסה של XML הופכות לאובייקטים של תצוגת Kotlin בזיכרון (או נוצרות מהן). אחרי שהפריסה מתרחבת, Activity יכול לצייר את האובייקטים האלה על המסך ולשנות אותם באופן דינמי.

תצוגות מפורטות

  • כל רכיבי ממשק המשתמש בפריסת האפליקציה הם מחלקות משנה של המחלקה View, והם נקראים תצוגות. ‫TextView ו-Button הן דוגמאות לצפיות.
  • אפשר לקבץ רכיבי View בתוך ViewGroup. קבוצת צפיות משמשת כקונטיינר לצפיות או לקבוצות צפיות אחרות שנכללות בה. ‫LinearLayout היא דוגמה לקבוצת תצוגות שמסודרות באופן לינארי.

הצגת מאפיינים

  • המאפיינים android:layout_width ו-android:layout_height מציינים את המשקל והגובה של תצוגה. הערך match_parent מרחיב את התצוגה לרוחב או לגובה של רכיב האב. הערך wrap_content מצמצם את התצוגה כך שתתאים לתוכן שלה.
  • המאפיין android:text מציין את הטקסט שצריך להציג בתצוגה (אם מוצג טקסט בתצוגה). במקרה של לחצנים, android:text היא התווית של הלחצן.
  • המאפיין android:orientation בקבוצת תצוגות LinearLayout מסדר את רכיבי התצוגה שהוא מכיל. ערך של horizontal מסדר את התצוגות משמאל לימין. ערך של vertical מסדר את התצוגות מלמעלה למטה.
  • המאפיין android:layout_gravity קובע את המיקום של תצוגה ושל כל הצאצאים של התצוגה הזו.
  • המאפיין android:textSize מגדיר את גודל הטקסט בתצוגת טקסט. גדלי הטקסט מוגדרים ביחידות sp (פיקסלים שניתן לשנות). כשמשתמשים ביחידות sp, אפשר לשנות את גודל הטקסט בלי קשר לאיכות התצוגה של המכשיר.

מחרוזות

  • במקום להגדיר מחרוזות בפריסה, מומלץ להשתמש במשאבי מחרוזות.
  • משאבי מחרוזות נמצאים בקובץ values/res/string.xml.
  • כדי לחלץ מחרוזות, משתמשים ב-Alt+Enter (Option+Enter ב-Mac). בתפריט הקופץ, בוחרים באפשרות Extract string resources (חילוץ משאבי מחרוזות).

שימוש בתצוגות

  • כדי לקשר את קוד Kotlin לתצוגה שהגדרתם בפריסה, צריך לקבל הפניה לאובייקט התצוגה אחרי שהתצוגה הורחבה. מקצים מזהה (android:id) לתצוגה בפריסה, ואז משתמשים בשיטה findViewById() כדי לקבל את אובייקט התצוגה המשויך.
  • כשיוצרים מזהה לתצוגה בקובץ הפריסה של XML, ‏ Android Studio יוצר קבוע מסוג integer עם השם של המזהה הזה במחלקה R שנוצרת. אחר כך אפשר להשתמש בהפניה R.id בשיטה findViewById().
  • אפשר להגדיר את המאפיינים של אובייקט תצוגה ישירות בקוד Kotlin לפי שם המאפיין. לדוגמה, הטקסט בתצוגת טקסט מוגדר על ידי המאפיין android:text ב-XML, והוא מוגדר על ידי המאפיין text ב-Kotlin.
  • click handler היא שיטה שמופעלת כשמשתמש לוחץ על אלמנט בממשק המשתמש או מקיש עליו. כדי לצרף שיטה לטיפול בלחיצות לתצוגה כמו לחצן, משתמשים בשיטה setOnClickListener().

שימוש בהודעות קצרות

הודעה קופצת היא תצוגה שבה מוצגת למשתמש הודעה פשוטה בחלון קופץ קטן.

כדי ליצור הודעה קופצת, קוראים לשיטת היצירה makeText() במחלקה Toast עם שלושה ארגומנטים:

  • ההקשר של האפליקציה Activity
  • ההודעה שתוצג, לדוגמה, משאב מחרוזת
  • משך זמן, לדוגמה Toast.LENGTH_SHORT

כדי להציג את ההודעה הקופצת, קוראים ל-show().

קורס ב-Udacity:

מסמכי תיעוד למפתחי Android:

אחר:

בקטע הזה מפורטות אפשרויות למשימות ביתיות לתלמידים שעובדים על ה-Codelab הזה כחלק מקורס בהנחיית מדריך. המורה צריך:

  • אם צריך, מקצים שיעורי בית.
  • להסביר לתלמידים איך להגיש מטלות.
  • בודקים את שיעורי הבית.

אנשי ההוראה יכולים להשתמש בהצעות האלה כמה שרוצים, ומומלץ להם להקצות כל שיעורי בית אחרים שהם חושבים שמתאימים.

אם אתם עובדים על ה-codelab הזה לבד, אתם יכולים להשתמש במשימות האלה כדי לבדוק את הידע שלכם.

שינוי אפליקציה

פותחים את האפליקציה DiceRoller. מוסיפים לאפליקציה לחצן עם התווית 'איפוס' שמופיע ממש מתחת ללחצן הטלת קובייה. הכפתור יאפס את תצוגת הטקסט של התוצאה ל-0.

עונים על השאלות הבאות

שאלה 1

איזו שיטה ב-Activity מרחיבה את הפריסה של האפליקציה והופכת את התצוגות שלה לזמינות כאובייקטים?

  • onCreate()
  • setClickListener()
  • setContentView()
  • show()

שאלה 2

באיזה מאפיין של תצוגה משתמשים כדי להגדיר את הרוחב של תצוגה כך שהוא יותאם לתוכן?

  • android:view_width="wrap"
  • android:layout_width="wrap_content"
  • android:layout_height="wrap_content"
  • android:layout_width="match_parent"

שליחת האפליקציה למתן ציון

בודקים שהאפליקציה כוללת את הדברים הבאים:

  • פריסת האפליקציה צריכה לכלול תצוגת טקסט אחת ושני לחצנים.
  • בקוד של האפליקציה צריך להגדיר שני click handlers, אחד לכל לחצן.
  • ה-click handler שמאפס את תצוגת הטקסט צריך להגדיר את מאפיין הטקסט ל-0.

עוברים לשיעור הבא: 1.3 משאבי תמונות ותאימות

קישורים ל-codelabs אחרים בקורס הזה מופיעים בדף הנחיתה של ה-codelabs בנושא יסודות Android Kotlin.