יום רביעי, נובמבר 3

ווידג'טים 3: Spinner


הכרנו כבר כמה מחלקות (classes) של widget, נזכיר את Button, EditText, TextView, ListView. נכיר עכשיו ווידג'ט חשוב נוסף: Spinner המוכר לפעמים במקומות אחרים כ-pull-down או תפריט גלילה. התפריט הזה מאפשר בחירה ע"י לחיצה וגלגול.
נבצע ונסביר תרגיל הכולל spinner. מטרת התרגיל: בחירה של שיר מתוך רשימת שירים.
הקלק על הלינק להורדת קבצי המקור. 
נתחיל מהסוף: ה-UI מוצג בתמונה הבאה:


בתצוגה הנ"ל מופיעים 4 אלמנטים (מלמעלה למטה):
  1. TextView עם הכותרת של ה-spinner
  2. ה-spinner
  3. כפתור להחלת הבחירה של ה-spinner (זאת העדפה שלי, אפשר לבצע בחירה ב-spinner גם ללא התניה בכפתור נוסף)
  4. TextView להצגת הבחירה.
כעת כשמטרת התרגיל ידועה, נסקור את קבצי הקוד.
נתחיל עם ה-layout:
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:orientation="vertical"
  4.     android:layout_width="fill_parent"
  5.     android:layout_height="fill_parent"
  6.     >
  7.     <TextView android:id="@+id/spinnerTitle"
  8.                 android:layout_width="wrap_content"
  9.                 android:layout_height="wrap_content"
  10.                 android:text="@string/spinner_title"
  11.                 android:layout_marginTop="30px" android:layout_marginBottom="20px" 
  12.                 android:layout_marginLeft="40px"
  13.     />
  14.        <Spinner    android:id="@+id/songs_spinner"
  15.                 android:layout_width="fill_parent"
  16.                 android:layout_height="wrap_content"
  17.                 android:layout_marginLeft="20px"
  18.     />
  19.        <Button        android:id="@+id/apply_button"
  20.                 android:text="@string/apply"
  21.                 android:layout_width="wrap_content"
  22.                 android:layout_height="wrap_content"
  23.                 android:layout_marginLeft="20px"
  24.     />
  25.     <TextView     android:id="@+id/output_box"
  26.                 android:layout_width="wrap_content"
  27.                 android:layout_height="wrap_content"
  28.                   android:layout_marginTop="30px" android:layout_marginBottom="20px"
  29.                 android:layout_marginLeft="20px"
  30.     />
  31. </LinearLayout>

ארבעת האלמנטים של התצוגה אותם ראינו מופיעים כאן. שימו לב ל-spinner - שורה 14. songs_spinner מתייחס ל-id שלו,  ובאמצעותו, כרגיל, נוכל להתייחס לאלמנט זה, כפי שנראה מיד. עד כאן ה-layout.

ה-spinner כאמור כולל רשימה של שירים. אפשר היה ליצר רשימה זו בתוך קובץ ה-java, כמו שנעשה בתרגיל של ה-ListView. מצד שני, שימוש ברשימה שנמצאת בקובץ נתונים מאפשרת הוספת או הורדת פריטים מהרשימה מבלי לגעת בקובץ java וזה בהחלט עדיף. היות שכך, את רשימת השירים נחזיק בקובץ res/values/array.xml, ובתוכו מערך בשם songsArray. לשם הנוחות תוכן הקובץ מוצג כאן:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <resources>
  3.     <array name="songsArray">             
  4.         <item>Valentino</item>             
  5.         <item>Yesterday</item>             
  6.         <item>My Way</item>             
  7.         <item>The Boxer</item>
  8.         <item>American Pie</item>             
  9.         <item>Niddles and Pins</item>
  10.         <item>Indian Summer</item>             
  11.         <item>Knowing Me Knowing You</item>             
  12.         <item>Rasputin</item>
  13.         <item>Elinor</item>             
  14.     </array>   
  15. </resources>


מעבר לקובץ ה-layout וה-array שהוצגו למעלה, שאר הקבצים די סטנדרטים (למשל strings.xml), כך שנוכל התרכז בעיקר - mySpinner.java.

הפעם מדובר בתרגיל פשוט, האובייקט mySpinner מכיל מתודה אחת בלבד - onCreate.
כרגיל, נציג תחילה את האובייקט כולו ואח"כ נסביר אותו.


  1. public class mySpinner extends Activity {
  2.     /** Called when the activity is first created. */
  3.         private Spinner songSelectSpinner;
  4.         private Button     applyButton;
  5.         private TextView textBox;   

  6. @Override
  7.     public void onCreate(Bundle savedInstanceState) {
  8.         super.onCreate(savedInstanceState);
  9.         this.setContentView(R.layout.main);
  10.         songSelectSpinner = (Spinner) findViewById(R.id.songs_spinner);
  11.         textBox    = (TextView)findViewById(R.id.output_box);
  12.         applyButton     = (Button)findViewById(R.id.apply_button);
  13.         ArrayAdapter<String> songsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources()
  14.             .getStringArray(R.array.songsArray));
  15.         songSelectSpinner.setAdapter(songsAdapter);
  16.         applyButton.setOnClickListener(new View.OnClickListener() {
  17.             public void onClick(View view) {
  18.                 String selectedSong =  getResources().getStringArray(R.array.songsArray)[songSelectSpinner.getSelectedItemPosition()];
  19.                 textBoxox.setText("Selected song is: " + selectedSong);
  20.             }
  21.         });
  22.     }
  23. }
התהליכים במתודה onCreate:
שלב 1. האיתחולים הרגילים: קריאה למתודת ה"אב" (super), ואתחול ה-UI בשורות 8-9.
שלב 2. הבאת 3 הווידג'טים על פי ה-id שלהם:

  1.         songSelectSpinner = (Spinner) findViewById(R.id.songs_spinner);
  2.         textBoxox    = (TextView)findViewById(R.id.output_box);
  3.         applyButton     = (Button)findViewById(R.id.apply_button);
שלב 3. יצירת המתאם (Adapter) בין הרשימה שתשמש כתפריט לבין הווידגט. בעזרת המתאם מחברים את רשימת השמות לאובייקט ה-spinner והופכים אותה לתפריט. הפרמטרים של ה-constructor:
  • context. ראה this.
  • ה-id של ה-resource. כאן אנחנו משתמשים בתבנית מוכנה מראש של אמדרואיד - simple_spinner_item. אנדרואיד כולל תבנית נוספת ל-spinner:נסו להחליף את  simple_spinner_item ב: simple_spinner_dropdown_item. העיצוב הגראפי שיתקבל יהיה מעט שונה.
  • רשימת הפריטים - במקרה שלנו רשימת השירים - הנמצאת בקובץ res/raw/array.xml.
אגב, יצירת ה-Adapter הודגמה כבר בתרגיל הקודם עבור ה-ListView. שם מערך השמות הוגדר בקובץ ה-java בתוך האובייקט.

   ArrayAdapter<String> songsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, getResources( .getStringArray(R.array.songsArray));

שלב 4. חיבור ה-Adapter לאובייקט.
ה-Adapter שנוצר בשלב -3, songsAdapter, מחובר לאובייקט ה-spinner ע"י המתודה setAdapter.
songSelectSpinner.setAdapter(songsAdapter);

זהו. יצירת ה-spinner הושלמה.

כעת נותר להגדיר את ה-callback שיחבר בין הלחיצה על הכפתור (הוספנו כאמור כפתור רגיל בשם applyButton) לבין שליפת האלמנט בתפריט שנבחר ב-spinner. יצירת ה-callback נעשית כרגיל - קרה למטה. בתוך המתודה onClick מתבצעות שתי פעולות:
שורה 3: שליפת שם השיר שנבחר.
שורה 4: הצגת השיר הנבחר ב-UI.

  1.        applyButton.setOnClickListener(new View.OnClickListener() {
  2.             public void onClick(View view) {
  3.                 String selectedSong =  getResources().getStringArray(R.array.songsArray)[songSelectSpinner.getSelectedItemPosition()];
  4.                 textBox.setText("Selected song is: " + selectedSong);
  5.             }
  6.         });
עד כאן ה-spinner. אני מכין פוסט בנושא MediaPlayer. נבנה שם נגן MP3 פשוט. אחרי כן, התוכנית היא להציג אפליקציה המשלבת את הנגן עם ה-spinner לבחירת השירים.
נ.ב.
"גיליתי" מדריך ל-spinner באתר המפתחים של אנדרואיד:
http://developer.android.com/resources/tutorials/views/hello-spinner.html
יש שם למעשה מדריך מעניין ל-widgets and views.
מקווה שהפוסט הנ"ל יסייע במתן אוריינטציה לחומר הרב המופיע באתר של אנדרואיד. זאת הרי אחת ממטרותיו בעצם.

2 תגובות:

  1. תודה רבה על כל ההעשרה והקדשת הזמן!

    ..לא מובן מאליו.

    השבמחק
  2. הי רונן צריכה עזרה במשהו אתה זמין?

    השבמחק