Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:laborator05 [2015/03/23 14:46]
Andrei Roșu-Cojocaru
laboratoare:laborator05 [2015/04/22 17:40] (current)
Andrei Roșu-Cojocaru [Spinner]
Line 6: Line 6:
   - de tip **container** (derivate din clasa ''​android.widget.AdapterView''​) responsabil pentru afișarea acestora pe ecran; el conține câte un element de tip ''​android.widget.View''​ pentru fiecare element al listei, oricât de complex;   - de tip **container** (derivate din clasa ''​android.widget.AdapterView''​) responsabil pentru afișarea acestora pe ecran; el conține câte un element de tip ''​android.widget.View''​ pentru fiecare element al listei, oricât de complex;
   - de tip **adaptor** (ce implementează interfața ''​android.widget.Adapter''​) care asigură ​   - de tip **adaptor** (ce implementează interfața ''​android.widget.Adapter''​) care asigură ​
-    - legătura dintre resursele care dețin datele respective (fișiere, furnizori de conținut) și controalele de pe suprafața de afișare, cu care interacționează utilizatorul;​ orice modificare asupra datelor va fi realizată prin intermediul acestei componente+    - legătura dintre resursele care dețin datele respective (fișiere, furnizori de conținut) și controalele de pe suprafața de afișare, cu care interacționează utilizatorul;​ orice modificare asupra datelor va fi realizată prin intermediul acestei componente;
     - modul de dispunere a informațiilor pentru fiecare element în parte. ​     - modul de dispunere a informațiilor pentru fiecare element în parte. ​
  
Line 20: Line 20:
  
 === ListView === === ListView ===
 +
 Un obiect de tip [[http://​developer.android.com/​reference/​android/​widget/​ListView.html|ListView]] afișează elementele pe care le conține vertical, existând posibilitatea ca acestea să fie derulate în situația în care se depășește dimensiunea suprafeței de afișare. ​ Un obiect de tip [[http://​developer.android.com/​reference/​android/​widget/​ListView.html|ListView]] afișează elementele pe care le conține vertical, existând posibilitatea ca acestea să fie derulate în situația în care se depășește dimensiunea suprafeței de afișare. ​
  
Line 28: Line 29:
 <file xml activity_movies.xml>​ <file xml activity_movies.xml>​
 <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​ +  ​xmlns:​tools="​http://​schemas.android.com/​tools"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​match_parent" ​  +  android:​layout_height="​match_parent" ​  
-    tools:​context="​.MoviesActivity"​ >+  tools:​context="​.MoviesActivity"​ >
  
-    ​<​ListView +  ​<​ListView 
-        android:​id="​@+id/​listview" +    android:​id="​@+id/​movies_list_view" 
-        android:​layout_width="​wrap_content"​ +    android:​layout_width="​wrap_content"​ 
-        android:​layout_height="​wrap_content"​ +    android:​layout_height="​wrap_content"​ 
-        android:​divider="​@color/​lightblue"​ +    android:​divider="​@color/​lightblue"​ 
-        android:​dividerHeight="​5dp" ​  />+    android:​dividerHeight="​5dp" ​  />
  
 </​RelativeLayout>​ </​RelativeLayout>​
Line 48: Line 49:
 public class MoviesActivity extends Activity { public class MoviesActivity extends Activity {
  
-    ​String[] movies = new String[] {  +  ​String[] movies = new String[] {  
-        "The Shawshank Redemption",​  +    "The Shawshank Redemption",​  
- "The Godfather",​  +    "The Godfather",​  
- "The Godfather: Part II",  +    "The Godfather: Part II",  
- "The Dark Knight",​  +    "The Dark Knight",​  
- "Pulp Fiction",​  +    "Pulp Fiction",​  
- "The Good, the Bad and the Ugly",  +    "The Good, the Bad and the Ugly",  
- "​Schindler'​s List",  +    "​Schindler'​s List",  
- "12 Angry Men",  +    "12 Angry Men",  
- "The Lord of the Rings: The Return of the King",  +    "The Lord of the Rings: The Return of the King",  
- "​Fight Club"  +    "Fight Club"  
-    };+  };
   
-    ​@Override +  ​@Override 
-    protected void onCreate(Bundle savedInstanceState) { +  protected void onCreate(Bundle savedInstanceState) { 
-        super.onCreate(savedInstanceState);​ +    super.onCreate(savedInstanceState);​ 
- setContentView(R.layout.activity_movies);​ +    setContentView(R.layout.activity_movies);​ 
- +     
- ListView listview = (ListView)findViewById(R.id.listview); +    ListView listview = (ListView)findViewById(R.id.movies_list_view); 
- final ArrayAdapter<​String>​ adapter = new ArrayAdapter<​String>​(this,​ android.R.layout.simple_list_item_1,​ movies); +    final ArrayAdapter<​String>​ adapter = new ArrayAdapter<​String>​(this,​ android.R.layout.simple_list_item_1,​ movies); 
- listview.setAdapter(adapter);​ +    listview.setAdapter(adapter);​ 
-    }+  }
 } }
 </​code>​ </​code>​
Line 83: Line 84:
 <code java> <code java>
 listview.setOnItemClickListener(new AdapterView.OnItemClickListener() { listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
-    ​@Override +  ​@Override 
-    public void onItemClick(AdapterView<?>​ parent, View view, int position, long id) { +  public void onItemClick(AdapterView<?>​ parent, View view, int position, long id) { 
-        Toast.makeText(MainActivity.this,​ "You have clicked on "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ +    Toast.makeText(MainActivity.this,​ "You have clicked on "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ 
-    }+  }
 }); });
 listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { listview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
-    ​@Override +  ​@Override 
-    public boolean onItemLongClick(AdapterView<?>​ parent, View view, int position, long id) { +  public boolean onItemLongClick(AdapterView<?>​ parent, View view, int position, long id) { 
-        Toast.makeText(MainActivity.this,​ "You have long clicked on "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ +    Toast.makeText(MainActivity.this,​ "You have long clicked on "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ 
- return true; +    return true; 
-    }+  }
 }); });
 listview.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { listview.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-    ​@Override +  ​@Override 
-    public void onItemSelected(AdapterView<?>​ parent, View view, int position, long id) { +  public void onItemSelected(AdapterView<?>​ parent, View view, int position, long id) { 
-        Toast.makeText(MainActivity.this,​ "You have selected the "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ +    Toast.makeText(MainActivity.this,​ "You have selected the "​+adapter.getItem(position)+"​ item", Toast.LENGTH_SHORT).show();​ 
-    } +  } 
-    @Override +  @Override 
-    public void onNothingSelected(AdapterView<?>​ parent) { +  public void onNothingSelected(AdapterView<?>​ parent) { 
-        Toast.makeText(MainActivity.this,​ "​Currently,​ the list has no item selected",​ Toast.LENGTH_SHORT).show();​ +    Toast.makeText(MainActivity.this,​ "​Currently,​ the list has no item selected",​ Toast.LENGTH_SHORT).show();​ 
-    }+  }
 }); });
 </​code>​ </​code>​
  
 Aceste metode de tratare a evenimentelor din clasele ascultător primesc ca parametri: Aceste metode de tratare a evenimentelor din clasele ascultător primesc ca parametri:
-  * un obiect de tip ''​AdapterView'',​ indicând lista din care a fost accesat un element +  * un obiect de tip ''​AdapterView'',​ indicând lista din care a fost accesat un element; 
-  * un ''​View'',​ reprezentând elementul din cadrul listei care a fost accesat +  * un ''​View'',​ reprezentând elementul din cadrul listei care a fost accesat; 
-  * poziția la care se află în listă elementul care a fost accesat+  * poziția la care se află în listă elementul care a fost accesat;
  
 <note important>​Numerotarea elementelor în cadrul listei se face începând cu 0.</​note>​ <note important>​Numerotarea elementelor în cadrul listei se face începând cu 0.</​note>​
Line 121: Line 122:
 <?xml version="​1.0"​ encoding="​utf-8"?>​ <?xml version="​1.0"​ encoding="​utf-8"?>​
 <​resources>​ <​resources>​
-    ​<string name="​app_name">​Top 10 Movies</​string>​ +  ​<string name="​app_name">​Top 10 Movies</​string>​ 
-    <​string-array name="​movies">​ +  <​string-array name="​movies">​ 
-        <​item>​The Shawshank Redemption</​item>​ +    <​item>​The Shawshank Redemption</​item>​ 
-        <​item>​The Godfather</​item>​ +    <​item>​The Godfather</​item>​ 
-        <​item>​The Godfather: Part II</​item>​ +    <​item>​The Godfather: Part II</​item>​ 
-        <​item>​The Dark Knight</​item>​ +    <​item>​The Dark Knight</​item>​ 
-        <​item>​Pulp Fiction</​item>​ +    <​item>​Pulp Fiction</​item>​ 
-        <​item>​The Good, the Bad and the Ugly</​item>​ +    <​item>​The Good, the Bad and the Ugly</​item>​ 
-        <​item>​Schindler&​apos;​s List</​item>​ +    <​item>​Schindler&​apos;​s List</​item>​ 
-        <​item>​12 Angry Men</​item>​ +    <​item>​12 Angry Men</​item>​ 
-        <​item>​The Lord of the Rings: The Return of the King</​item>​ +    <​item>​The Lord of the Rings: The Return of the King</​item>​ 
-        <​item>​Fight Club</​item>​ +    <​item>​Fight Club</​item>​ 
-    </​string-array>​+  </​string-array>​
 </​resources>​ </​resources>​
 </​file>​ </​file>​
Line 155: Line 156:
   * unul singur: ''​ListView.CHOICE_MODE_SINGLE''​   * unul singur: ''​ListView.CHOICE_MODE_SINGLE''​
   * mai multe: ''​ListView.CHOICE_MODE_MULTIPLE''​   * mai multe: ''​ListView.CHOICE_MODE_MULTIPLE''​
-Aceste constante vor fi transmise ca parametru metodei ''​setChoiceMode''​ definită de clasa ''​ListView''​. +Aceste constante vor fi transmise ca parametru metodei ''​setChoiceMode()''​ definită de clasa ''​ListView''​. 
-Pentru a se determina intrările care au fost selectate de utilizator, va fi parcursă întreaga listă (numărul de elemente fiind obținut prin metoda ''​getCount''​),​ starea în care se găsesc acestea fiind verificată prin intermediul meteodei ''​isItemChecked(int)''​ care primește ca parametru poziția din listă pentru care se dorește să se realizeze textul.+Pentru a se determina intrările care au fost selectate de utilizator, va fi parcursă întreaga listă (numărul de elemente fiind obținut prin metoda ''​getCount()''​),​ starea în care se găsesc acestea fiind verificată prin intermediul meteodei ''​isItemChecked(int)''​ care primește ca parametru poziția din listă pentru care se dorește să se realizeze textul.
 <code java> <code java>
 String itemsSelected = "You have selected the following items:​\n";​ String itemsSelected = "You have selected the following items:​\n";​
 for (int position = 0; position < listview.getCount();​ position++) for (int position = 0; position < listview.getCount();​ position++)
-    ​if (listview.isChecked(position)) +  ​if (listview.isChecked(position)) ​{ 
-        itemsSelected += " * "​+listview.getItemAtPosition(position)+"​\n";​+    itemsSelected += " * "​+listview.getItemAtPosition(position)+"​\n";​ 
 +  }
 </​code>​ </​code>​
  
Line 167: Line 169:
  
 == ExpandableListView == == ExpandableListView ==
 +
 Un caz particular de listă este ''​ExpandableListView'',​ care permite asocierea conținuturilor în grupuri, acestea putând fi expandate. ​ Un caz particular de listă este ''​ExpandableListView'',​ care permite asocierea conținuturilor în grupuri, acestea putând fi expandate. ​
  
Line 181: Line 184:
 <file xml activity_contacts.xml>​ <file xml activity_contacts.xml>​
 <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​+  ​xmlns:​tools="​http://​schemas.android.com/​tools" 
 +  android:​layout_width="​match_parent"​ 
 +  android:​layout_height="​match_parent"​ 
 +  tools:​context="​.ContactsActivity"​ > 
 + 
 +  <​GridView 
 +    android:​id="​@+id/​contacts_grid_view"
     android:​layout_width="​match_parent"​     android:​layout_width="​match_parent"​
     android:​layout_height="​match_parent"​     android:​layout_height="​match_parent"​
-    ​tools:​context="​.ContactsActivity"​ > +    android:​horizontalSpacing="​10dp"​ 
- +    android:​verticalSpacing="​10dp"​ 
-    <​GridView +    android:​numColumns="​auto_fit"​ 
-        android:​id="​@+id/​gridview"​ +    android:​gravity="​center" ​> 
-        android:​layout_width="​match_parent"​ +     
-        android:​layout_height="​match_parent"​ +    <!-- grid layout content --> 
-        ​android:​horizontalSpacing="​10dp"​ +     
-        android:​verticalSpacing="​10dp"​ +  </GridLayout>
-        android:​numColumns="​auto_fit"​ +
-        android:​gravity="​center"​ />+
  
 </​RelativeLayout>​ </​RelativeLayout>​
Line 201: Line 208:
 public class ContactsActivity extends Activity implements LoaderManager.LoaderCallbacks<​Cursor>​ { public class ContactsActivity extends Activity implements LoaderManager.LoaderCallbacks<​Cursor>​ {
  
-    ​GridView gridview; +  ​GridView gridview; 
-    SimpleCursorAdapter adapter;+  SimpleCursorAdapter adapter;
         
-    ​@Override +  ​@Override 
-    protected void onCreate(Bundle savedInstanceState) { +  protected void onCreate(Bundle savedInstanceState) { 
-        super.onCreate(savedInstanceState);​ +    super.onCreate(savedInstanceState);​ 
- setContentView(R.layout.activity_main);​ +    setContentView(R.layout.activity_main);​ 
-  +     
- gridview = (GridView)findViewById(R.id.gridview); +    gridview = (GridView)findViewById(R.id.contacts_grid_view); 
- String[] projections = new String[] {Contacts.DISPLAY_NAME};​ +    String[] projections = new String[] {Contacts.DISPLAY_NAME};​ 
-        int[] views = new int[] {android.R.id.text1};​  +    int[] views = new int[] {android.R.id.text1};​  
- adapter = new SimpleCursorAdapter(this,​ android.R.layout.simple_list_item_1,​ null, projections,​ views, 0); +    adapter = new SimpleCursorAdapter(this,​ android.R.layout.simple_list_item_1,​ null, projections,​ views, 0); 
- gridview.setAdapter(adapter);​ +    gridview.setAdapter(adapter);​ 
- getLoaderManager().initLoader(0,​ null, this); +    getLoaderManager().initLoader(0,​ null, this); 
-    }+  }
   
-    ​public Loader<​Cursor>​ onCreateLoader(int id, Bundle data) { +  ​public Loader<​Cursor>​ onCreateLoader(int id, Bundle data) { 
-        return new CursorLoader(this,​ Contacts.CONTENT_URI,​ null, null, null, Contacts.DISPLAY_NAME);​ +    return new CursorLoader(this,​ Contacts.CONTENT_URI,​ null, null, null, Contacts.DISPLAY_NAME);​ 
-    }+  }
   
-    ​public void onLoadFinished(Loader<​Cursor>​ loader, Cursor cursor) { +  ​public void onLoadFinished(Loader<​Cursor>​ loader, Cursor cursor) { 
-        adapter.swapCursor(cursor);​  +    adapter.swapCursor(cursor);​  
-    }+  }
   
-    ​public void onLoaderReset(Loader<​Cursor>​ loader) { +  ​public void onLoaderReset(Loader<​Cursor>​ loader) { 
-        adapter.swapCursor(null);​ +    adapter.swapCursor(null);​ 
-    }+  }
 } }
 </​file>​ </​file>​
Line 252: Line 259:
 <code xml> <code xml>
 <Spinner <Spinner
-    ​android:​id="​@+id/​spinner"​ +  ​android:​id="​@+id/​spinner"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​wrap_content"​ +  android:​layout_height="​wrap_content"​ 
-    android:​entries="​@array/​device_manufacturer"​ +  android:​entries="​@array/​device_manufacturer"​ 
-    android:​spinnerMode="​dialog"​ +  android:​spinnerMode="​dialog"​ 
-    android:​prompt="​@string/​prompt"​ />+  android:​prompt="​@string/​prompt"​ />
 </​code>​ </​code>​
  
Line 264: Line 271:
 <code xml> <code xml>
 <Spinner <Spinner
-    ​android:​id="​@+id/​spinner"​ +  ​android:​id="​@+id/​spinner"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​wrap_content"​ +  android:​layout_height="​wrap_content"​ 
-    android:​entries="​@array/​device_manufacturer"​ +  android:​entries="​@array/​device_manufacturer"​ 
-    android:​spinnerMode="​dropdown"​ +  android:​spinnerMode="​dropdown"​ 
-    android:​dropDownHorizontalOffset="​10dp"​ +  android:​dropDownHorizontalOffset="​10dp"​ 
-    android:​dropDownVerticalOffset="​10dp"​ +  android:​dropDownVerticalOffset="​10dp"​ 
-    android:​popupBackground="​@drawable/​mobiledevice"​ +  android:​popupBackground="​@drawable/​mobiledevice"​ 
-    android:​dropDownSelector="​@color/​lightblue"​ />+  android:​dropDownSelector="​@color/​lightblue"​ />
 </​code>​ </​code>​
 </​columns>​ </​columns>​
  
-{{ :​laboratoare:​laborator05:​sample_spinner_dialog.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​sample_spinner_dialog.png?​nolink&​400 }}
  
-{{ :​laboratoare:​laborator05:​sample_spinner_dropdown.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​sample_spinner_dropdown.png?​nolink&​400 }}
  
 Pentru un astfel de obiect vor trebui specificate două mecanisme de afișare a conținutului:​ Pentru un astfel de obiect vor trebui specificate două mecanisme de afișare a conținutului:​
Line 305: Line 312:
 <file xml attrs.xml>​ <file xml attrs.xml>​
 <​resources>​ <​resources>​
-    ​<​declare-styleable name="​gallery">​ +  ​<​declare-styleable name="​gallery">​ 
-        <attr name="​android:​galleryItemBackground"​ /> +    <attr name="​android:​galleryItemBackground"​ /> 
-    </​declare-styleable>​+  </​declare-styleable>​
 </​resources>​ </​resources>​
 </​file>​ </​file>​
Line 325: Line 332:
 <file xml activity_faculty.xml> ​ <file xml activity_faculty.xml> ​
 <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​+  ​xmlns:​tools="​http://​schemas.android.com/​tools" 
 +  android:​layout_width="​match_parent"​ 
 +  android:​layout_height="​match_parent"​ 
 +  android:​orientation="​vertical"​ 
 +  tools:​context="​.FacultyActivity"​ > 
 +  <​TextView 
 +    android:​id="​@+id/​textview"
     android:​layout_width="​match_parent"​     android:​layout_width="​match_parent"​
-    android:​layout_height="​match_parent" +    android:​layout_height="​wrap_content" 
-    ​android:​orientation="​vertical"​ +    android:​gravity="​center"​ 
-    tools:​context="​.FacultyActivity"​ > +    android:​text="​@string/​app_name"​ 
-    <​TextView +    android:​textSize="​16sp"​ /> 
-        android:​id="​@+id/​textview"​ +  <​Gallery 
-        android:​layout_width="​match_parent"​ +    android:​id="​@+id/​gallery"​ 
-        android:​layout_height="​wrap_content"​ +    android:​layout_width="​match_parent"​ 
-        ​android:​gravity="​center"​ +    android:​layout_height="​wrap_content"​ 
-        android:​text="​@string/​app_name"​ +    android:​padding="​10dp"​  
-        android:​textSize="​16sp"​ /> +    android:​animationDuration="​500"​ 
-    <​Gallery +    android:​spacing="​5dp"​ 
-        android:​id="​@+id/​gallery"​ +    android:​unselectedAlpha="​0.5"​ /> 
-        android:​layout_width="​match_parent"​ +  <​ImageView 
-        android:​layout_height="​wrap_content"​ +    android:​id="​@+id/​imageview"​ 
-        android:​padding="​10dp"​  +    android:​layout_gravity="​center"​ 
-        android:​animationDuration="​500"​ +    android:​padding="​10dp"​ 
-        android:​spacing="​5dp"​ +    android:​layout_width="​320dp"​ 
-        android:​unselectedAlpha="​0.5"​ /> +    android:​layout_height="​240dp"​ 
-    <​ImageView +    android:​scaleType="​fitXY"​ 
-        android:​id="​@+id/​imageview"​ +    android:​contentDescription="​@string/​content_description"​ />
-        android:​layout_gravity="​center"​ +
-        android:​padding="​10dp"​ +
-        android:​layout_width="​320dp"​ +
-        android:​layout_height="​240dp"​ +
-        android:​scaleType="​fitXY"​ +
-        android:​contentDescription="​@string/​content_description"​ />+
 </​LinearLayout>​ </​LinearLayout>​
 </​file>​ </​file>​
Line 361: Line 368:
 public class FacultyActivity extends Activity { public class FacultyActivity extends Activity {
  
-    ​Integer[] facultyImages = { +  ​Integer[] facultyImages = { 
-        R.drawable.faculty01,​ +    R.drawable.faculty01,​ 
-        R.drawable.faculty02,​ +    R.drawable.faculty02,​ 
-        R.drawable.faculty03 +    R.drawable.faculty03 
-        // add resources for other faculties +    // add resources for other faculties 
-    }; +  };
   
-    ​class GalleryAdapter extends BaseAdapter { +  ​class GalleryAdapter extends BaseAdapter { 
- Context context; +    Context context; 
-  +     
- public ImageAdapter(Context context) { +    public ImageAdapter(Context context) { 
-     ​this.context = context; +      this.context = context;
- } +
-  +
- public int getCount() { +
-     return facultyImages.length;​ +
-        } +
-  +
- public Object getItem(int position) { +
-     return position; +
- } +
-  +
- public long getItemId(int position) { +
-     return position; +
- } +
-  +
- public View getView(int position, View convertView,​ ViewGroup parent) { +
-     ImageView imageview;​ +
-     if (convertView == null) { +
-         imageview = new ImageView(context);​ +
- imageview.setImageResource(facultyImages [position]);​ +
- imageview.setScaleType(ImageView.ScaleType.FIT_XY);​ +
- imageview.setLayoutParams(new Gallery.LayoutParams(160,​ 120)); +
-     } +
-     else +
- imageview = (ImageView)convertView;​ +
-     return imageview;​ +
- }+
     }     }
- +    ​ 
-    ​@Override +    public ​int getCount() { 
-    protected void onCreate(Bundle savedInstanceState) { +      ​return facultyImages.length;
-        super.onCreate(savedInstanceState);​ +
- setContentView(R.layout.activity_faculty);​ +
-  +
- Gallery gallery = (Gallery)findViewById(R.id.gallery);​ +
- gallery.setAdapter(new GalleryAdapter(this));​ +
- gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() { +
-     ​public ​void onItemClick(AdapterView<?>​ parent, View view, int position, long id) { +
- ImageView imageview = (ImageView)(findViewById(R.id.imageview));​ +
- imageview.setImageResource(facultyImages [position]);​ +
-     } +
- });+
     }     }
 +    ​
 +    public Object getItem(int position) {
 +      return position;
 +    }
 +    ​
 +    public long getItemId(int position) {
 +      return position;
 +    }
 +    ​
 +    public View getView(int position, View convertView,​ ViewGroup parent) {
 +      ImageView imageview;
 +      if (convertView == null) {
 +        imageview = new ImageView(context);​
 +        imageview.setImageResource(facultyImages [position]);​
 +        imageview.setScaleType(ImageView.ScaleType.FIT_XY);​
 +        imageview.setLayoutParams(new Gallery.LayoutParams(160,​ 120));
 +      } else {
 +        imageview = (ImageView)convertView;​
 +      }
 +      return imageview;
 +    }
 +  }
 +
 +  @Override
 +  protected void onCreate(Bundle savedInstanceState) {
 +    super.onCreate(savedInstanceState);​
 +    setContentView(R.layout.activity_faculty);​
 +    ​
 +    Gallery gallery = (Gallery)findViewById(R.id.gallery);​
 +    gallery.setAdapter(new GalleryAdapter(this));​
 +    gallery.setOnItemClickListener(new AdapterView.OnItemClickListener() {
 +      @Override
 +      public void onItemClick(AdapterView<?>​ parent, View view, int position, long id) {
 +        ImageView imageview = (ImageView)(findViewById(R.id.imageview));​
 +        imageview.setImageResource(facultyImages [position]);​
 +      }
 +    });
 +  }
 } }
 </​file>​ </​file>​
  
-{{ :​laboratoare:​laborator05:​sample_gallery.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​sample_gallery.png?​nolink&​400 }}
  
 ==== Tipuri de adaptoare pentru colecții de date ==== ==== Tipuri de adaptoare pentru colecții de date ====
Line 458: Line 466:
   - modificarea elementelor din sursa de date cu notificarea obiectului adaptor asociat prin intermediul metodei ''​notifyDataSetChanged()'',​ astfel încât operațiile realizate asupra sursei de date să se propage și la nivelul controlului grafic care îi afișează conținutul.   - modificarea elementelor din sursa de date cu notificarea obiectului adaptor asociat prin intermediul metodei ''​notifyDataSetChanged()'',​ astfel încât operațiile realizate asupra sursei de date să se propage și la nivelul controlului grafic care îi afișează conținutul.
  
-<note tip>​Metodele pentru modificarea colecției de date prin intermediul obiectului de tip adaptor (''​add'',​ ''​addAll'',​ ''​clear'',​ ''​insert'',​ ''​remove''​) apelează în mod automat ''​notifyDataSetChanged''​. Acest comportament poate fi suprascris prin intermediul metodei ''​setNotifyOnChange(boolean)''​.</​note>​+<note tip>​Metodele pentru modificarea colecției de date prin intermediul obiectului de tip adaptor (''​add'',​ ''​addAll'',​ ''​clear'',​ ''​insert'',​ ''​remove''​) apelează în mod automat ''​notifyDataSetChanged()''​. Acest comportament poate fi suprascris prin intermediul metodei ''​setNotifyOnChange(boolean)''​.</​note>​
  
 <note tip>​Ordonarea elementelor din sursa de date poate fi realizată prin obiectul de tip adapter, pe baza unui criteriu de comparare, prin intermediul metodei ''​sort(Comparator<?​ super T>​)''​.</​note>​ <note tip>​Ordonarea elementelor din sursa de date poate fi realizată prin obiectul de tip adapter, pe baza unui criteriu de comparare, prin intermediul metodei ''​sort(Comparator<?​ super T>​)''​.</​note>​
Line 519: Line 527:
 <?xml version="​1.0"​ encoding="​UTF-8"?>​ <?xml version="​1.0"​ encoding="​UTF-8"?>​
 <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​ +  ​xmlns:​tools="​http://​schemas.android.com/​tools"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​match_parent"​ > +  android:​layout_height="​match_parent"​ > 
-    <​ImageView +  <​ImageView 
-        android:​id="​@+id/​imageview"​ +    android:​id="​@+id/​imageview"​ 
-        android:​layout_width="​wrap_content"​ +    android:​layout_width="​wrap_content"​ 
-        android:​layout_height="​wrap_content"​ +    android:​layout_height="​wrap_content"​ 
-        android:​padding="​2dp"​ +    android:​padding="​2dp"​ 
-        android:​contentDescription="​@string/​content_description"​ /> +    android:​contentDescription="​@string/​content_description"​ /> 
-    <​TextView +  <​TextView 
-        android:​id="​@+id/​textview"​ +    android:​id="​@+id/​textview"​ 
-        android:​layout_width="​wrap_content"​ +    android:​layout_width="​wrap_content"​ 
-        android:​layout_height="​wrap_content"​ />+    android:​layout_height="​wrap_content"​ />
 </​LinearLayout>​ </​LinearLayout>​
 </​file>​ </​file>​
Line 539: Line 547:
 <code java> <code java>
 class PointArrayAdapter extends ArrayAdapter<​Point>​ { class PointArrayAdapter extends ArrayAdapter<​Point>​ {
-    ​private Context context; +  ​private Context context; 
-    private int resource; +  private int resource; 
-    private ArrayList<​Point>​ content;+  private ArrayList<​Point>​ content;
   
-    ​public PointArrayAdapter(Context context, int resource, ArrayList<​Point>​ content) { +  ​public PointArrayAdapter(Context context, int resource, ArrayList<​Point>​ content) { 
-        super(context,​ resource, content); +    super(context,​ resource, content); 
- this.context = context; +    this.context = context; 
- this.resource = resource; +    this.resource = resource; 
- this.content = content; +    this.content = content; 
-    }+  }
   
-    ​@Override +  ​@Override 
-    public View getView(int position, View convertView,​ ViewGroup parent) { +  public View getView(int position, View convertView,​ ViewGroup parent) { 
- View view; +    View view; 
- if (convertView == null) { +    if (convertView == null) { 
-            LayoutInflater layoutinflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);​ +      LayoutInflater layoutinflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);​ 
-     ​view = layoutinflator.inflate(resource,​ null); +      view = layoutinflator.inflate(resource,​ null); 
- } +    } else { 
- else +      view = convertView;​
-     ​view = convertView; +
- ImageView imageview = (ImageView)view.findViewById(R.id.imageview);​ +
- TextView textview = (TextView)view.findViewById(R.id.textview);​ +
- Point point = content.get(position);​ +
- if (point.getX() >= 0 && point.getY() >= 0) +
-     imageview.setImageResource(R.drawable.firstquadrant);​ +
- else if (point.getX() < 0 && point.getY() >= 0) +
-     imageview.setImageResource(R.drawable.secondquadrant);​ +
- else if (point.getX() < 0 && point.getY() < 0) +
-     imageview.setImageResource(R.drawable.thirdquadrant);​ +
- else if (point.getX() >= 0 && point.getY() < 0) +
-     imageview.setImageResource(R.drawable.forthquadrant);​ +
- textview.setText(point.toString());​ +
- return view;+
     }     }
 +    ImageView imageview = (ImageView)view.findViewById(R.id.imageview);​
 +    TextView textview = (TextView)view.findViewById(R.id.textview);​
 +    Point point = content.get(position);​
 +    if (point.getX() >= 0 && point.getY() >= 0) {
 +      imageview.setImageResource(R.drawable.firstquadrant);​
 +    } else if (point.getX() < 0 && point.getY() >= 0) {
 +      imageview.setImageResource(R.drawable.secondquadrant);​
 +    } else if (point.getX() < 0 && point.getY() < 0) {
 +      imageview.setImageResource(R.drawable.thirdquadrant);​
 +    } else if (point.getX() >= 0 && point.getY() < 0) {
 +      imageview.setImageResource(R.drawable.forthquadrant);​
 +    }
 +    textview.setText(point.toString());​
 +    return view;
 +  }
 } }
 </​code>​ </​code>​
Line 589: Line 598:
 </​code>​ </​code>​
  
-{{ :​laboratoare:​sample_base_adapter.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​sample_base_addapter.png?​nolink&​400 }}
  
 === SimpleCursorAdapter === === SimpleCursorAdapter ===
Line 631: Line 640:
 <file java CalendarActivity.java>​ <file java CalendarActivity.java>​
 public class CalendarActivity extends Activity { public class CalendarActivity extends Activity {
-    ​@Override +  ​@Override 
-    protected void onCreate(Bundle savedInstanceState) { +  protected void onCreate(Bundle savedInstanceState) { 
-        super.onCreate(savedInstanceState);​ +    super.onCreate(savedInstanceState);​ 
- setContentView(R.layout.activity_main);​ +    setContentView(R.layout.activity_main);​ 
- Cursor cursor = getContentResolver().query( +    Cursor cursor = getContentResolver().query( 
-                            Calendars.CONTENT_URI,​  +        Calendars.CONTENT_URI,​  
-                            new String[]{Calendars._ID,​ Calendars.CALENDAR_DISPLAY_NAME,​ Calendars.CALENDAR_TIME_ZONE},​  +        new String[]{Calendars._ID,​ Calendars.CALENDAR_DISPLAY_NAME,​ Calendars.CALENDAR_TIME_ZONE},​  
-     ​null,  +        null,  
-     ​null,  +        null, 
-     ​null); +        null); 
- SimpleCursorAdapter adapter = new SimpleCursorAdapter( +    SimpleCursorAdapter adapter = new SimpleCursorAdapter( 
-                                          this,  +        this, 
-                                   ​android.R.layout.two_line_list_item,​  +        android.R.layout.two_line_list_item,​ 
-           ​cursor,  +        cursor, 
-           ​new String[]{Calendars.CALENDAR_DISPLAY_NAME,​ Calendars.CALENDAR_TIME_ZONE},​  +        new String[]{Calendars.CALENDAR_DISPLAY_NAME,​ Calendars.CALENDAR_TIME_ZONE},​ 
-           ​new int[] {android.R.id.text1,​ android.R.id.text2},​  +        new int[] {android.R.id.text1,​ android.R.id.text2},​  
-           ​0); + 0); 
- ListView listview = (ListView)findViewById(R.id.listview);​ +    ListView listview = (ListView)findViewById(R.id.listview);​ 
- listview.setAdapter(adapter);​ +    listview.setAdapter(adapter);​ 
-    }+  }
 } }
 </​file>​ </​file>​
Line 674: Line 683:
 public class StaffMemberActivity extends Activity { public class StaffMemberActivity extends Activity {
  
-    ​@Override +  ​@Override 
-    protected void onCreate(Bundle savedInstanceState) { +  protected void onCreate(Bundle savedInstanceState) { 
-        super.onCreate(savedInstanceState);​ +    super.onCreate(savedInstanceState);​ 
- setContentView(R.layout.activity_staff_member);​ +    setContentView(R.layout.activity_staff_member);​ 
- +     
- try { +    try { 
-            InputStream inputstream = getAssets().open("​staffmember.xml"​);​ +      InputStream inputstream = getAssets().open("​staffmember.xml"​);​ 
-     ​StaffXmlParser staffxmlparser = new StaffXmlParser();​ +      StaffXmlParser staffxmlparser = new StaffXmlParser();​ 
-     ​List<​Map<​String,?>>​ staffmembers = staffxmlparser.parse(inputstream);​ +      List<​Map<​String,?>>​ staffmembers = staffxmlparser.parse(inputstream);​ 
-     ​SimpleAdapter adapter = new SimpleAdapter( +      SimpleAdapter adapter = new SimpleAdapter( 
-                                        this, +          this, 
- staffmembers,​ +          staffmembers,​ 
- android.R.layout.simple_list_item_2,​ +          android.R.layout.simple_list_item_2,​ 
- new String[] {"​name",​ "​position"​},​ +          new String[] {"​name",​ "​position"​},​ 
- new int[] {android.R.id.text1,​ android.R.id.text2});​ +          new int[] {android.R.id.text1,​ android.R.id.text2});​ 
-            ListView listview = (ListView)findViewById(R.id.listview) +      ListView listview = (ListView)findViewById(R.id.listview) 
-            listview.setAdapter(adapter);​ +      listview.setAdapter(adapter);​ 
-        } catch (Exception exception) { +    } catch (Exception exception) { 
-     ​Log.println(Log.ERROR,​ "​exception",​ exception.getMessage());​ +      Log.println(Log.ERROR,​ "​exception",​ exception.getMessage());​
- }+
     }     }
 +  }
 } }
 </​file>​ </​file>​
Line 711: Line 720:
 </​code>​ </​code>​
  
-  * metoda ''​getCount''​ furnizează numărul de elemente din cadrul listei; +  * metoda ''​getCount()''​ furnizează numărul de elemente din cadrul listei; 
-  * metoda ''​getItem''​ întoarce elementul care se află pe o anumită poziție în cadrul listei; +  * metoda ''​getItem()''​ întoarce elementul care se află pe o anumită poziție în cadrul listei; 
-  * metoda ''​getItemId''​ returnează identificatorul elementului de pe o anumită poziție în cadrul listei; +  * metoda ''​getItemId()''​ returnează identificatorul elementului de pe o anumită poziție în cadrul listei; 
-  * metoda ''​getView''​ construiește un control grafic corespunzător elementului de pe o anumită poziție în cadrul listei; acesta poate fi o instanță nouă, existând totodată posibilitatea de a se reutiliza parametrul ''​convertView''​ (care reprezintă o componentă a listei creată anterior, ce nu mai este vizibilă, putând fi astfel reciclată);​ obiectul ''​parent''​ indică elementul de tip container în care este afișat conținutul sursei de date.+  * metoda ''​getView()''​ construiește un control grafic corespunzător elementului de pe o anumită poziție în cadrul listei; acesta poate fi o instanță nouă, existând totodată posibilitatea de a se reutiliza parametrul ''​convertView''​ (care reprezintă o componentă a listei creată anterior, ce nu mai este vizibilă, putând fi astfel reciclată);​ obiectul ''​parent''​ indică elementul de tip container în care este afișat conținutul sursei de date.
  
 <note important>​Clasa care implementează tipul de adaptor definit de utilizator trebuie să conțină (intern) și modelul de date, operând asupra acestuia.</​note> ​ <note important>​Clasa care implementează tipul de adaptor definit de utilizator trebuie să conțină (intern) și modelul de date, operând asupra acestuia.</​note> ​
Line 725: Line 734:
 </​code>​ </​code>​
  
-  * metoda ''​getViewTypeCount''​ va întoarce numărul tipurilor de layout-uri care vor fi afișate în cadrul listei; +  * metoda ''​getViewTypeCount()''​ va întoarce numărul tipurilor de layout-uri care vor fi afișate în cadrul listei; 
-  * metoda ''​getItemViewType''​ returnează - pentru elementul aflat pe o anumită poziție - mecanismul de dispunere care va fi utilizat.+  * metoda ''​getItemViewType()''​ returnează - pentru elementul aflat pe o anumită poziție - mecanismul de dispunere care va fi utilizat.
  
-Spre exemplu, pentru gestiunea unei liste formată dintr-un ''​ImageView''​ și două ''​TextView'',​ dispuse diferit în funcție de rândul pe care se găsesc, vor trebui definite două layout-uri (în ''/​res/​layout''​) - denumite ''​odd_layout.xml''​ și ''​even_layout.xml''​ ce vor fi încărcate de metoda ''​getView''​ în funcție de poziția respectivă:​+Spre exemplu, pentru gestiunea unei liste formată dintr-un ''​ImageView''​ și două ''​TextView'',​ dispuse diferit în funcție de rândul pe care se găsesc, vor trebui definite două layout-uri (în ''/​res/​layout''​) - denumite ''​odd_layout.xml''​ și ''​even_layout.xml''​ ce vor fi încărcate de metoda ''​getView()''​ în funcție de poziția respectivă:​
  
 {{ :​laboratoare:​laborator05:​listview_definit_de_utilizator.png?​nolink }} {{ :​laboratoare:​laborator05:​listview_definit_de_utilizator.png?​nolink }}
Line 735: Line 744:
 public class CustomAdapter extends BaseAdapter { public class CustomAdapter extends BaseAdapter {
  
-    ​Activity context; +  ​Activity context; 
-    List<​CustomObject>​ data;+  List<​CustomObject>​ data;
  
-    ​// ...+  ​// ...
  
-    ​@Override +  ​@Override 
-    public View getView(int position, View convertView,​ ViewGroup parent) { +  public View getView(int position, View convertView,​ ViewGroup parent) { 
-        View customView;​ +    View customView;​ 
-        CustomObject customObject = data.get(position);​ +    CustomObject customObject = data.get(position);​ 
-        LayoutInflater layoutInflater = (LayoutInflater)context.getLayoutInflater();​ +    LayoutInflater layoutInflater = (LayoutInflater)context.getLayoutInflater();​ 
-        if (position % 2 == 0) +    if (position % 2 == 0) { 
-           ​customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); +       ​customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); 
-        else +    ​} ​else { 
-           ​customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false); +       ​customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false);
-        ImageView imageView = (ImageView)customView.findViewById(R.id.imageView);​ +
-        imageView.setImageResource(customObject.getImageId());​ +
-        TextView textView1 = (TextView)customView.findViewById(R.id.textView1);​ +
-        textView1.setText(customObject.getText1());​ +
-        TextView textView2 = (TextView)customView.findViewById(R.id.textView2);​ +
-        textView2.setText(customObject.getText2());​ +
-        return customView;+
     }     }
 +    ImageView imageView = (ImageView)customView.findViewById(R.id.imageView);​
 +    imageView.setImageResource(customObject.getImageId());​
 +    TextView textView1 = (TextView)customView.findViewById(R.id.textView1);​
 +    textView1.setText(customObject.getText1());​
 +    TextView textView2 = (TextView)customView.findViewById(R.id.textView2);​
 +    textView2.setText(customObject.getText2());​
 +    return customView;
 +  }
 } }
 </​code>​ Clasa adaptor definită de utilizator va trebui să rețină referințe către context (activitatea în cadrul căreia este afișată lista) și către sursa de date. </​code>​ Clasa adaptor definită de utilizator va trebui să rețină referințe către context (activitatea în cadrul căreia este afișată lista) și către sursa de date.
  
-Metoda ''​getView''​ construiește un element de pe o anumită poziție din cadrul listei pe care îl va întoarce apoi ca rezultat.+Metoda ''​getView()''​ construiește un element de pe o anumită poziție din cadrul listei pe care îl va întoarce apoi ca rezultat.
  
 Inițial, trebuie să se obțină conținutul intrării din listă ce trebuie afișată (considerându-se o corespondență 1:1 între conținutul sursei de date și elementele listei) și să se instanțieze obiectul responsabil cu expandarea layout-ului. Ulterior se obține obiectul de tip ''​View''​ pe baza mecanismului de dispunere (corespunzător poziției curente) specificat în fișierul XML. Acesta va furniza referințe către controalele din cadrul său (prin intermediul identificatorilor unici) pentru care se va putea specifica conținutul,​ preluat din obiectul curent al sursei de date. Inițial, trebuie să se obțină conținutul intrării din listă ce trebuie afișată (considerându-se o corespondență 1:1 între conținutul sursei de date și elementele listei) și să se instanțieze obiectul responsabil cu expandarea layout-ului. Ulterior se obține obiectul de tip ''​View''​ pe baza mecanismului de dispunere (corespunzător poziției curente) specificat în fișierul XML. Acesta va furniza referințe către controalele din cadrul său (prin intermediul identificatorilor unici) pentru care se va putea specifica conținutul,​ preluat din obiectul curent al sursei de date.
  
 == Tehnici pentru optimizarea performanțelor == == Tehnici pentru optimizarea performanțelor ==
 +
 Implementarea unor tehnici pentru optimizarea performanțelor este foarte importantă atunci când se dezvoltă aplicații pentru dispozitive mobile. Având în vedere resursele limitate (în special în privința memoriei și a capacității de procesare) de care dispun acestea, un program care nu le gestionează în mod eficient poate determina o depreciere a timpului de răspuns. Implementarea unor tehnici pentru optimizarea performanțelor este foarte importantă atunci când se dezvoltă aplicații pentru dispozitive mobile. Având în vedere resursele limitate (în special în privința memoriei și a capacității de procesare) de care dispun acestea, un program care nu le gestionează în mod eficient poate determina o depreciere a timpului de răspuns.
  
-Fiecare element din cadrul unei liste este un ''​View''​ obținut prin expandarea layout-ului,​ atât construirea obiectului pentru gestiunea modurilor de dispunere (metoda ''​getLayoutInflater''​) cât și operația de instanțiere a unei intrări din listă pe baza specificației XML (metoda ''​inflate''​) ​ fiind operații extrem de costisitoare. De asemenea, obținerea unei referințe către un control din cadrul interfeței grafice pe baza identificatorului său (metoda ''​findViewById''​) poate avea afecta performanțele aplicației.+Fiecare element din cadrul unei liste este un ''​View''​ obținut prin expandarea layout-ului,​ atât construirea obiectului pentru gestiunea modurilor de dispunere (metoda ''​getLayoutInflater()''​) cât și operația de instanțiere a unei intrări din listă pe baza specificației XML (metoda ''​inflate()''​) ​ fiind operații extrem de costisitoare. De asemenea, obținerea unei referințe către un control din cadrul interfeței grafice pe baza identificatorului său (metoda ''​findViewById()''​) poate avea afecta performanțele aplicației.
  
 Printre cele mai utilizate tehnici pentru optimizarea performanțelor se numără: Printre cele mai utilizate tehnici pentru optimizarea performanțelor se numără:
Line 773: Line 784:
   * **instanțierea obiectului responsabil cu expandarea mecanismului de dispunere a unui element din cadrul listei pe constructorul clasei adaptor** <code java>   * **instanțierea obiectului responsabil cu expandarea mecanismului de dispunere a unui element din cadrul listei pe constructorul clasei adaptor** <code java>
 public CustomAdapter(Activity context, List<​CustomObject>​ data) { public CustomAdapter(Activity context, List<​CustomObject>​ data) {
-    ​this.data = data; +  ​this.data = data; 
-    layoutInflater = (LayoutInflater)context.getLayoutInflater();​+  layoutInflater = (LayoutInflater)context.getLayoutInflater();​
 } }
 </​code>​ În acest fel, se evită apelul acestei metode - costisitoare din punctul de vedere al utilizării resurselor - de fiecare dată când trebuie creat un element al listei. </​code>​ În acest fel, se evită apelul acestei metode - costisitoare din punctul de vedere al utilizării resurselor - de fiecare dată când trebuie creat un element al listei.
-  * **reutilizarea elementelor din cadrul listei care nu mai sunt vizibile** \\ De regulă, o listă conține mai multe elemente decât pot fi reprezentate pe suprafața de afișare a dispozitivului mobil, parcurgerea lor implicând folosirea unui mecanism de derulare. Obiectele corespunzătoare unor intrări care nu sunt vizibile la un moment dat pot fi reutilizate,​ ele fiind transmise în metoda ''​getView''​ prin intermediul parametrului ''​convertView'',​ prevenindu-se astfel operația de expandare a layout-ului.\\ <code java>​@Override+  * **reutilizarea elementelor din cadrul listei care nu mai sunt vizibile** \\ De regulă, o listă conține mai multe elemente decât pot fi reprezentate pe suprafața de afișare a dispozitivului mobil, parcurgerea lor implicând folosirea unui mecanism de derulare. Obiectele corespunzătoare unor intrări care nu sunt vizibile la un moment dat pot fi reutilizate,​ ele fiind transmise în metoda ''​getView()''​ prin intermediul parametrului ''​convertView'',​ prevenindu-se astfel operația de expandare a layout-ului.\\ <code java> 
 +@Override
 public View getView(int position, View convertView,​ ViewGroup parent) { public View getView(int position, View convertView,​ ViewGroup parent) {
-    ​View customView;​ +  ​View customView;​ 
-    CustomObject customObject = data.get(position);​ +  CustomObject customObject = data.get(position);​ 
-    if (convertView == null) { +  if (convertView == null) { 
-        if (position % 2 == 0) +    if (position % 2 == 0) { 
-           ​customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); +      customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); 
-        else +    ​} ​else { 
-           ​customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false);+      customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false);
     }     }
-    ​else +  } 
-        customView = convertView;​ +  ​else { 
-    // ... +    customView = convertView;​ 
-    return customView;+  } 
 +  ​// ... 
 +  return customView;
 } }
-</​code>​ Prin această metodă se evită apelarea metodei ''​inflate''​ de fiecare dată când trebuie să se afișeze un element al listei.  +</​code>​ Prin această metodă se evită apelarea metodei ''​inflate()''​ de fiecare dată când trebuie să se afișeze un element al listei.  
-<note important>​Nu întotdeauna este posibilă reutilizarea obiectelor ce reprezintă elemente ale listei, situație în care parametrul ''​convertView''​ are valoarea ''​null''​. De aceea, în metoda ''​getView''​ trebuie verificată întotdeauna valoarea acestui parametru.</​note>​  +<note important>​Nu întotdeauna este posibilă reutilizarea obiectelor ce reprezintă elemente ale listei, situație în care parametrul ''​convertView''​ are valoarea ''​null''​. De aceea, în metoda ''​getView()''​ trebuie verificată întotdeauna valoarea acestui parametru.</​note>​  
-<note warning> În cazul în care există mai multe posibilități de dispunere în cadrul listei, există riscul ca tipul de element care va fi reutilizat să nu fie cel necesar. Pentru a se asigura evitarea unei astfel de situații, este necesară suprascrierea metodelor ''​getViewTypeCount'',​ respectiv ''​getItemViewType''​.+<note warning> În cazul în care există mai multe posibilități de dispunere în cadrul listei, există riscul ca tipul de element care va fi reutilizat să nu fie cel necesar. Pentru a se asigura evitarea unei astfel de situații, este necesară suprascrierea metodelor ''​getViewTypeCount()'',​ respectiv ''​getItemViewType()''​.
 <code java> <code java>
 public final static int LIST_VIEW_TYPES ​    ​= 2; public final static int LIST_VIEW_TYPES ​    ​= 2;
Line 801: Line 815:
     
 public ​int getViewTypeCount() { public ​int getViewTypeCount() {
-    ​return LIST_VIEW_TYPES; ​+  ​return LIST_VIEW_TYPES; ​
 } }
 public Object getItemViewType(int position) { public Object getItemViewType(int position) {
-    ​if (position % 2 == 0)     +  ​if (position % 2 == 0)     
-        ​return LIST_VIEW_TYPE_ODD;​ +    ​return LIST_VIEW_TYPE_ODD;​ 
-    return ​LIST_VIEW_TYPE_EVEN;​+  return ​LIST_VIEW_TYPE_EVEN;​
 } }
 </​code>​ </​code>​
 </​note> ​ </​note> ​
-  * **reținerea unei referințe către structura layout-ului prin intermediul unor etichete**\\ În acest scop se utilizează un șablon denumit ''​ViewHolder''​ prin intermediul căruia pot fi accesate controalele grafice din cadrul unui element al listei, fără a fi necesară utilizarea identificatorului din cadrul documentului XML.\\ \\ ''​ViewHolder''​ este o clasă internă din cadrul adaptorului,​ definind exact structura pe care o are layout-ul unei intrări din cadrul listei. În momentul în care un obiect corespunzător unui element al listei este creat, în atributele clasei ''​ViewHolder''​ se rețin referințe către controalele grafice, acestea fiind atașate, ca etichetă, prin intermediul metodei ''​setTag''​. Ulterior, ele vor fi preluate (prin metoda ''​getTag''​),​ utilizându-se referințele către elementele componente în loc să se apeleze metoda ''​findViewById''​ de fiecare data, rezultatul fiind o apreciere a performanțelor cu circa 15%.\\ <code java>+  * **reținerea unei referințe către structura layout-ului prin intermediul unor etichete**\\ În acest scop se utilizează un șablon denumit ''​ViewHolder''​ prin intermediul căruia pot fi accesate controalele grafice din cadrul unui element al listei, fără a fi necesară utilizarea identificatorului din cadrul documentului XML.\\ \\ ''​ViewHolder''​ este o clasă internă din cadrul adaptorului,​ definind exact structura pe care o are layout-ul unei intrări din cadrul listei. În momentul în care un obiect corespunzător unui element al listei este creat, în atributele clasei ''​ViewHolder''​ se rețin referințe către controalele grafice, acestea fiind atașate, ca etichetă, prin intermediul metodei ''​setTag()''​. Ulterior, ele vor fi preluate (prin metoda ''​getTag()''​),​ utilizându-se referințele către elementele componente în loc să se apeleze metoda ''​findViewById()''​ de fiecare data, rezultatul fiind o apreciere a performanțelor cu circa 15%.\\ <code java>
 public class CustomAdapter extends BaseAdapter { public class CustomAdapter extends BaseAdapter {
  
-    ​public static class ViewHolder { +  ​public static class ViewHolder { 
-        ImageView imageView;​ +    ImageView imageView;​ 
-        TextView textView1, textView2;​ +    TextView textView1, textView2;​ 
-    };+  };
  
-    ​// ...+  ​// ...
   
-    ​@Override +  ​@Override 
-    public View getView(int position, View convertView,​ ViewGroup parent) { +  public View getView(int position, View convertView,​ ViewGroup parent) { 
-        View customView;​ +    View customView;​ 
-        ViewHolder viewHolder;​ +    ViewHolder viewHolder;​ 
-        CustomObject customObject = (CustomObject)data.get(position);​ +    CustomObject customObject = (CustomObject)data.get(position);​ 
-        if (convertView == null) { +    if (convertView == null) { 
-            if (position % 2 == 0) +      if (position % 2 == 0) { 
-                customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); +        customView = layoutInflater.inflate(R.layout.odd_layout,​ parent, false); 
-            else +      ​} ​else { 
-                customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false); +        customView = layoutInflater.inflate(R.layout.even_layout,​ parent, false); 
-            viewHolder = new ViewHolder();​ +      } 
-            viewHolder.imageView = (ImageView)customView.findViewById(R.id.imageView);​ +      ​viewHolder = new ViewHolder();​ 
-            viewHolder.textView1 = (TextView)customView.findViewById(R.id.textView1);​ +      viewHolder.imageView = (ImageView)customView.findViewById(R.id.imageView);​ 
-            viewHolder.textView2 = (TextView)customView.findViewById(R.id.textView2);​ +      viewHolder.textView1 = (TextView)customView.findViewById(R.id.textView1);​ 
-            customView.setTag(viewHolder);​  +      viewHolder.textView2 = (TextView)customView.findViewById(R.id.textView2);​ 
- } +      customView.setTag(viewHolder);​ 
- else +    } else { 
-     ​customView = convertView; +      customView = convertView;​
- viewHolder = (ViewHolder)customView.getTag();​ +
- viewHolder.imageView.setImageResource(customObject.getImageeId());​ +
- viewHolder.textView1.setText(customObject.getText1());​ +
- viewHolder.textView2.setText(customObject.getText2());​ +
-  +
-        return customView;+
     }     }
 +    viewHolder = (ViewHolder)customView.getTag();​
 +    viewHolder.imageView.setImageResource(customObject.getImageeId());​
 +    viewHolder.textView1.setText(customObject.getText1());​
 +    viewHolder.textView2.setText(customObject.getText2());​
 +    ​
 +    return customView;
 +  }
 } }
 </​code>​ </​code>​
Line 855: Line 870:
 <code xml> <code xml>
 <​ListView <​ListView
-    ​android:​id="​@android:​id/​list"​ +  ​android:​id="​@android:​id/​list"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​wrap_content"​ />+  android:​layout_height="​wrap_content"​ />
 </​code>​ </​code>​
 </​note>​ </​note>​
Line 882: Line 897:
   * ''​v''​ - elementul din cadrul listei care a fost apăsat ​   * ''​v''​ - elementul din cadrul listei care a fost apăsat ​
   * ''​position''​ - poziția elementului care a fost apăsat în cadrul listei   * ''​position''​ - poziția elementului care a fost apăsat în cadrul listei
-  * ''​id''​ - identificatorul elementului care a fost apăsat în cadrul listei (întors de metoda ''​getItemId''​ a clasei adaptor)+  * ''​id''​ - identificatorul elementului care a fost apăsat în cadrul listei (întors de metoda ''​getItemId()''​ a clasei adaptor)
  
 Clasa ''​ListActivity''​ nu definește însă și o metodă pentru tratarea apăsărilor de lungă durată (//eng.// long-click),​ în acest sens fiind necesară implementarea unei clase ascultător ce implementează interfața ''​AdapterView.OnItemLongClickListener'',​ asociată obiectului de tip ''​ListView''​ din cadrul ferestrei. Clasa ''​ListActivity''​ nu definește însă și o metodă pentru tratarea apăsărilor de lungă durată (//eng.// long-click),​ în acest sens fiind necesară implementarea unei clase ascultător ce implementează interfața ''​AdapterView.OnItemLongClickListener'',​ asociată obiectului de tip ''​ListView''​ din cadrul ferestrei.
Line 896: Line 911:
 Metodele pe care le pune la dispoziție ''​ListFragment''​ sunt similare cu cele oferite de ''​ListActivity''​. Metodele pe care le pune la dispoziție ''​ListFragment''​ sunt similare cu cele oferite de ''​ListActivity''​.
  
-<note important>​În cazul în care se dorește gestiunea unei aplicații cu mai multe fragmente utilizând liste, acestea vor fi incluse într-o fereastră ce extinde ''​FragmentActivity''​ și nu ''​ListActivity'',​ în caz contrar evenimentele de tip apăsare a unui element fiind consumate de clasa părinte.\\ Se recomandă folosirea claselor definite în pachetul ''​android.support.v4.app''​.+<note important>​În cazul în care se dorește gestiunea unei aplicații cu mai multe fragmente utilizând liste, acestea vor fi incluse într-o fereastră ce extinde ''​FragmentActivity''​ și nu ''​ListActivity'',​ în caz contrar evenimentele de tip apăsare a unui element fiind consumate de clasa părinte.
 </​note>​ </​note>​
  
-Pentru utilizarea de layout-uri definite de utilizatori,​ lista implicită trebuie referită prin ''​android:​id/​list'',​ mecanismul de dispunere fiind încărcat pe metoda ''​onCreateView''​.+Pentru utilizarea de layout-uri definite de utilizatori,​ lista implicită trebuie referită prin ''​android:​id/​list'',​ mecanismul de dispunere fiind încărcat pe metoda ''​onCreateView()''​.
  
 <code java> <code java>
 @Override @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) { public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
-    ​View view = inflater.inflate(R.layout.fragment_custom,​ container, false); +  ​View view = inflater.inflate(R.layout.fragment_custom,​ container, false); 
-    return view;+  return view;
 } }
 </​code>​ </​code>​
Line 913: Line 928:
 @Override @Override
 public void onActivityCreated(Bundle state) { public void onActivityCreated(Bundle state) {
-    ​super.onActivityCreated(state);​ +  ​super.onActivityCreated(state);​ 
-    CustomAdapter customAdapter = new CustomAdapter(getActivity(),​ data); +  CustomAdapter customAdapter = new CustomAdapter(getActivity(),​ data); 
-    setListAdapter(customAdapter);​ +  setListAdapter(customAdapter);​
 } }
 </​code>​ </​code>​
Line 924: Line 939:
   - **static**, dacă fragmentul respectiv nu va fi înlocuit în cadrul interfeței grafice (sau în situația în care este înlocuit, el este păstrat pe stivă prin apelul metodei ''​addToBackStack()'',​ pentru a se putea reveni la el)\\ <code xml>   - **static**, dacă fragmentul respectiv nu va fi înlocuit în cadrul interfeței grafice (sau în situația în care este înlocuit, el este păstrat pe stivă prin apelul metodei ''​addToBackStack()'',​ pentru a se putea reveni la el)\\ <code xml>
 <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​ +  ​xmlns:​tools="​http://​schemas.android.com/​tools"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​match_parent"​ +  android:​layout_height="​match_parent"​ 
-    tools:​context="​.MainActivity"​ >+  tools:​context="​.MainActivity"​ >
  
-    ​<​fragment +  ​<​fragment 
-        android:​id="​@+id/​fragment1"​ +    android:​id="​@+id/​fragment1"​ 
-        android:​name="​ro.pub.cs.pdsd.laborator04.view.Fragment1"​ +    android:​name="​ro.pub.cs.systems.pdsd.lab05.Fragment1"​ 
-        android:​layout_width="​match_parent"​ +    android:​layout_width="​match_parent"​ 
-        android:​layout_height="​wrap_content"​ />+    android:​layout_height="​wrap_content"​ />
  
 </​RelativeLayout>​ </​RelativeLayout>​
Line 946: Line 961:
 </​code>​ De remarcat faptul că pentru fragment au fost specificate următoarele proprietăți:​ </​code>​ De remarcat faptul că pentru fragment au fost specificate următoarele proprietăți:​
     * ''​android:​id''​ prin intermediul căruia fragmentul poate fi identificat în mod unic (alternativ se poate specifica ''​android:​tag''​)     * ''​android:​id''​ prin intermediul căruia fragmentul poate fi identificat în mod unic (alternativ se poate specifica ''​android:​tag''​)
-    * ''​android:​name''​ reprezentând clasa corespunzătoare fragmentului,​ care va fi instanțiată în momentul în care este expandat layoutul corespunzător activității (în locul elementului ''<​fragment>''​ va fi plasat rezultatul metodei ''​onCreateView''​)\\ ​+    * ''​android:​name''​ reprezentând clasa corespunzătoare fragmentului,​ care va fi instanțiată în momentul în care este expandat layoutul corespunzător activității (în locul elementului ''<​fragment>''​ va fi plasat rezultatul metodei ''​onCreateView()''​)\\ ​
   - **dinamic**,​ în situația în care conținutul fragmentului va fi diferit, în funcție de anumite operații realizate de utilizator\\ <code xml>   - **dinamic**,​ în situația în care conținutul fragmentului va fi diferit, în funcție de anumite operații realizate de utilizator\\ <code xml>
 <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​RelativeLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
-    ​xmlns:​tools="​http://​schemas.android.com/​tools"​ +  ​xmlns:​tools="​http://​schemas.android.com/​tools"​ 
-    android:​layout_width="​match_parent"​ +  android:​layout_width="​match_parent"​ 
-    android:​layout_height="​match_parent"​ +  android:​layout_height="​match_parent"​ 
-    tools:​context="​.CartoonActivity"​ >+  tools:​context="​.CartoonActivity"​ >
   ​   ​
-    ​<​FrameLayout  +  ​<​FrameLayout  
-        android:​id="​@+id/​fragment1"​ +    android:​id="​@+id/​fragment1"​ 
-        android:​layout_width="​0dp"​ +    android:​layout_width="​0dp"​ 
-        android:​layout_height="​match_parent"​ +    android:​layout_height="​match_parent"​ 
-        android:​layout_weight="​1"​ />+    android:​layout_weight="​1"​ />
  
 </​RelativeLayout>​ </​RelativeLayout>​
Line 978: Line 993:
   * 0 sau mai multe submeniuri (reprezentate de clasa ''​android.view.SubMenu''​)   * 0 sau mai multe submeniuri (reprezentate de clasa ''​android.view.SubMenu''​)
   * 0 sau mai multe intrări propriu-zise (reprezentate de clasa ''​android.view.MenuItem''​),​ caracterizate prin următoarele atribute:   * 0 sau mai multe intrări propriu-zise (reprezentate de clasa ''​android.view.MenuItem''​),​ caracterizate prin următoarele atribute:
-    * **denumire** reprezintă valoarea care este afișată în cadrul interfeței grafice +    * **denumire** reprezintă valoarea care este afișată în cadrul interfeței grafice; 
-    * **identificator** generat de obicei în mod automat pentru meniurile declarate prin intermediul fișierelor XML +    * **identificator** generat de obicei în mod automat pentru meniurile declarate prin intermediul fișierelor XML; 
-    * **identificator al grupului de meniuri** prin intermediul căruia mai multe opțiuni din cadrul meniului pot fi grupate împreună+    * **identificator al grupului de meniuri** prin intermediul căruia mai multe opțiuni din cadrul meniului pot fi grupate împreună;
     * **număr de ordine** specifică importanța intrării, determinând o sortare a acestora, fiind folosit pentru a se indica ordinea de afișare a meniurilor sau pentru a preciza faptul că întregul grup aparține unei categorii (identificatorul grupului de meniuri fiind același cu numărul de ordine); unele intervale sunt rezervate pentru anumite categorii de meniuri     * **număr de ordine** specifică importanța intrării, determinând o sortare a acestora, fiind folosit pentru a se indica ordinea de afișare a meniurilor sau pentru a preciza faptul că întregul grup aparține unei categorii (identificatorul grupului de meniuri fiind același cu numărul de ordine); unele intervale sunt rezervate pentru anumite categorii de meniuri
  
Line 1000: Line 1015:
 @Override @Override
 public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
-    ​// populate menu, via XML resource file or programatically +  ​// populate menu, via XML resource file or programatically 
-    return true;+  return true;
 } }
 </​code>​ </​code>​
Line 1007: Line 1022:
 Pentru sistemele Android anterioare versiunii 2.3.x, aceasta este apelată în mod automat atunci când utilizatorul accesează meniul, iar pentru sistemele Android anterioare versiunii 3.0 în momentul instanțierii activității,​ de vreme ce opțiunile meniului trebuie să fie accesibile și prin intermediul barei de acțiuni. Pentru sistemele Android anterioare versiunii 2.3.x, aceasta este apelată în mod automat atunci când utilizatorul accesează meniul, iar pentru sistemele Android anterioare versiunii 3.0 în momentul instanțierii activității,​ de vreme ce opțiunile meniului trebuie să fie accesibile și prin intermediul barei de acțiuni.
  
-<note important>​Este foarte important ca rezultatul metodei ''​onCreateOptionsMenu''​ să fie ''​true'',​ pentru a face meniul vizibil. În situația în care metoda întoarce ''​false'',​ meniul va fi invizibil. </​note>​+<note important>​Este foarte important ca rezultatul metodei ''​onCreateOptionsMenu()''​ să fie ''​true'',​ pentru a face meniul vizibil. În situația în care metoda întoarce ''​false'',​ meniul va fi invizibil. </​note>​
  
 Mai multe informații cu privire la meniuri pot fi consultate [[http://​developer.android.com/​guide/​topics/​ui/​menus.html|aici]]. Mai multe informații cu privire la meniuri pot fi consultate [[http://​developer.android.com/​guide/​topics/​ui/​menus.html|aici]].
Line 1016: Line 1031:
  
 **1.** **prin intermediul unui fișier de resurse XML** plasat în ''​res/​menu''​ - variantă preferată datorită faptului că: **1.** **prin intermediul unui fișier de resurse XML** plasat în ''​res/​menu''​ - variantă preferată datorită faptului că:
-  * meniul poate fi identificat prin intermediul unei denumiri (generată în mod automat în clasa ''​R.menu''​) +  * meniul poate fi identificat prin intermediul unei denumiri (generată în mod automat în clasa ''​R.menu''​); 
-  * intrările propriu-zise din cadrul meniului vor fi ordonate în mod automat, generarea identificatorilor corespunzătoare acestora realizându-se de asemenea automat +  * intrările propriu-zise din cadrul meniului vor fi ordonate în mod automat, generarea identificatorilor corespunzători acestora realizându-se de asemenea automat; 
-  * textele conținute vor fi localizate automat (prin referințele la fișierele ce conțin șiruri de caractere) +  * textele conținute vor fi localizate automat (prin referințele la fișierele ce conțin șiruri de caractere); 
-  * structura poate fi vizualizată mai clar, separându-se partea de prezentare (conținutului meniului) de logica aplicației (mecanismul de răspuns la acțiunile utilizatorului vis-a-vis de intrările ale meniului) +  * structura poate fi vizualizată mai clar, separându-se partea de prezentare (conținutului meniului) de logica aplicației (mecanismul de răspuns la acțiunile utilizatorului vis-a-vis de intrările ale meniului); 
-  * permite definirea de configurații diferite pentru diverse platforme (dimensiuni ale suprafeței de afișare)+  * permite definirea de configurații diferite pentru diverse platforme (dimensiuni ale suprafeței de afișare).
  
 <file xml /​res/​menu/​main.xml>​ <file xml /​res/​menu/​main.xml>​
 <menu xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ > <menu xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ >
-    ​<item +  ​<item 
-        android:​id="​@+id/​operations"​ +    android:​id="​@+id/​operations"​ 
- android:​title="​@string/​operations"​ > +    android:​title="​@string/​operations"​ > 
- <​menu>​ +    <​menu>​ 
-     ​<item +      <item 
-                android:​id="​@+id/​create"​ +        android:​id="​@+id/​create"​ 
- android:​icon="​@drawable/​create" + android:​icon="​@drawable/​create"​
- android:​orderInCategory="​100"​ +
- android:​showAsAction="​ifRoom"​ +
- android:​title="​@string/​create"​ /> +
-            <!-- add other submenu entries -->​  ​    +
-        </​menu>​ +
-    </​item>​ +
-    <group +
-        android:​id="​@+id/​generic_actions"​ +
-        android:​visible="​true"​ +
-        android:​enabled="​true"​ +
-        android:​checkableBehavior="​none"​ > +
-        <item +
-            android:​id="​@+id/​settings"​ +
-            android:​icon="​@drawable/​settings"​ +
-            android:​orderInCategory="​100"​ +
-            android:​showAsAction="​ifRoom"​ +
-     android:​title="​@string/​settings"​ /> +
-        <!-- add other menu entries --> +
-    </​group>​ +
-    <item +
-        android:​id="​@+id/​help"​ +
-        android:​icon="​@drawable/​help"+
         android:​orderInCategory="​100"​         android:​orderInCategory="​100"​
-        ​android:​showAsAction="​ifRoom"​ + android:​showAsAction="​ifRoom"​ 
-        android:​title="​@string/​help" /> + android:​title="​@string/​create" /> 
-    <!-- add other menu entries --> +      <!-- add other submenu entries -->​  ​   ​ 
 +    ​</​menu>​ 
 +  </​item>​ 
 +  <group 
 +    android:​id="​@+id/​generic_actions"​ 
 +    android:​visible="​true"​ 
 +    android:​enabled="​true"​ 
 +    android:​checkableBehavior="​none"​ > 
 +    <item 
 +      android:​id="​@+id/​settings"​ 
 +      android:​icon="​@drawable/​settings"​ 
 +      android:​orderInCategory="​100"​ 
 +      android:​showAsAction="​ifRoom"​ 
 +      android:​title="​@string/​settings"​ /> 
 +    <!-- add other menu entries --> 
 +  </​group>​ 
 +  <item 
 +    android:​id="​@+id/​help"​ 
 +    android:​icon="​@drawable/​help"​ 
 +    android:​orderInCategory="​100"​ 
 +    android:​showAsAction="​ifRoom"​ 
 +    android:​title="​@string/​help"​ /> 
 +  ​<!-- add other menu entries -->
 </​menu>​ </​menu>​
 </​file>​ </​file>​
Line 1062: Line 1077:
  
 **a.** ''<​item>''​ care creează **a.** ''<​item>''​ care creează
-  * un submeniu (de tip ''​android.view.Submenu''​) în cazul în care are imbricat un alt element de tip ''<​menu>''​ +  * un submeniu (de tip ''​android.view.Submenu''​) în cazul în care are imbricat un alt element de tip ''<​menu>''​; 
-  * o intrare propriu-zisă a meniului (de tip ''​android.view.MenuItem''​),​ dacă nu conține alte elemente+  * o intrare propriu-zisă a meniului (de tip ''​android.view.MenuItem''​),​ dacă nu conține alte elemente;
 Atributele elementului ''<​item>''​ sunt: Atributele elementului ''<​item>''​ sunt:
   * ''​android:​id''​ - un identificator unic pentru resursă care va fi utilizat ca referință pentru elementul respectiv   * ''​android:​id''​ - un identificator unic pentru resursă care va fi utilizat ca referință pentru elementul respectiv
Line 1090: Line 1105:
 @Override @Override
 public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
-    ​getMenuInflater().inflate(R.menu.main,​ menu); +  ​getMenuInflater().inflate(R.menu.main,​ menu); 
-    return true;+  return true;
 } }
 </​code>​ </​code>​
  
-**2.** **programatic**,​ în codul sursă, de regulă în cadrul metodei ''​onCreateOptionsMenu''​+**2.** **programatic**,​ în codul sursă, de regulă în cadrul metodei ''​onCreateOptionsMenu()''​
 Metodele prin intermediul cărora sunt adăugate intrări în cadrul meniului sunt: Metodele prin intermediul cărora sunt adăugate intrări în cadrul meniului sunt:
 <code java> <code java>
Line 1124: Line 1139:
 @Override @Override
 public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
-    ​MenuItem menuItem;+  ​MenuItem menuItem;
     ​     ​
-    ​SubMenu subMenu = menu.addSubMenu(GROUP_ID_NONE,​ SUBMENU_ID_OPERATIONS,​ MENU_ORDER, R.string.operations);​ +  ​SubMenu subMenu = menu.addSubMenu(GROUP_ID_NONE,​ SUBMENU_ID_OPERATIONS,​ MENU_ORDER, R.string.operations);​ 
-    menuItem = subMenu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​ +  menuItem = subMenu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​ 
-    menuItem.setIcon(R.drawable.create);​ +  menuItem.setIcon(R.drawable.create);​ 
-    menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ +  menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ 
-    // add other submenu entries+  // add other submenu entries
     ​     ​
-    ​menuItem = menu.add(GROUP_ID_GENERIC_ACTIONS,​ MENU_ID_SETTINGS,​ MENU_ORDER, R.string.settings);​ +  ​menuItem = menu.add(GROUP_ID_GENERIC_ACTIONS,​ MENU_ID_SETTINGS,​ MENU_ORDER, R.string.settings);​ 
-    menuItem.setIcon(R.drawable.settings);​ +  menuItem.setIcon(R.drawable.settings);​ 
-    menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ +  menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ 
-    // add other menu entries+  // add other menu entries
     ​     ​
-    ​menu.setGroupVisible(GROUP_ID_GENERIC_ACTIONS,​ true); +  ​menu.setGroupVisible(GROUP_ID_GENERIC_ACTIONS,​ true); 
-    menu.setGroupEnabled(GROUP_ID_GENERIC_ACTIONS,​ true); +  menu.setGroupEnabled(GROUP_ID_GENERIC_ACTIONS,​ true); 
-    menu.setGroupCheckable(GROUP_ID_GENERIC_ACTIONS,​ false, false);+  menu.setGroupCheckable(GROUP_ID_GENERIC_ACTIONS,​ false, false);
     ​     ​
-    ​menuItem = menu.add(GROUP_ID_NONE,​ MENU_ID_SETTINGS,​ MENU_ORDER, R.string.about);​ +  ​menuItem = menu.add(GROUP_ID_NONE,​ MENU_ID_SETTINGS,​ MENU_ORDER, R.string.about);​ 
-    menuItem.setIcon(R.drawable.about);​ +  menuItem.setIcon(R.drawable.about);​ 
-    menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ +  menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);​ 
-    // add other menu entries+  // add other menu entries
     ​     ​
-    ​return true;+  ​return true;
 } }
 </​code>​ </​code>​
Line 1153: Line 1168:
  
 Alte metode utile puse la dispoziție de clasa ''​Menu''​ sunt: Alte metode utile puse la dispoziție de clasa ''​Menu''​ sunt:
-  * ''​findItem(int)''​ - întoarce un obiect de tip ''​MenuItem'',​ dându-se identificatorul acestuia +  * ''​findItem(int)''​ - întoarce un obiect de tip ''​MenuItem'',​ dându-se identificatorul acestuia; 
-  * ''​getItem(int)''​ - întoarce un obiect de tip ''​MenuITem'',​ dându-se poziția acestuia +  * ''​getItem(int)''​ - întoarce un obiect de tip ''​MenuITem'',​ dându-se poziția acestuia; 
-  * ''​removeGroup(int)''​ - șterge toate elementele din cadrul unui grup, furnizându-se identificatorul acestuia +  * ''​removeGroup(int)''​ - șterge toate elementele din cadrul unui grup, furnizându-se identificatorul acestuia; 
-  * ''​clear()''​ - șterge toate intrările intrărilor din cadrul meniului, acesta rămânând vid +  * ''​clear()''​ - șterge toate intrările intrărilor din cadrul meniului, acesta rămânând vid; 
-  * ''​removeItem(int)''​ - șterge o intrare din cadrul meniului, dându-se identificatorul acestuia +  * ''​removeItem(int)''​ - șterge o intrare din cadrul meniului, dându-se identificatorul acestuia; 
-  * ''​size()''​ - furnizează numărul de intrări din cadrul meniului +  * ''​size()''​ - furnizează numărul de intrări din cadrul meniului; 
-  * ''​hasVisibleItems()''​ - precizează dacă există intrări din cadrul meniului care sunt vizible sau nu +  * ''​hasVisibleItems()''​ - precizează dacă există intrări din cadrul meniului care sunt vizible sau nu; 
-  * ''​close()''​ - determină închiderea meniului, în cazul în care acesta este deschis+  * ''​close()''​ - determină închiderea meniului, în cazul în care acesta este deschis.
  
 <note tip>În situația în care sunt definite meniuri atât pentru activitate cât și pentru fragmentele pe care le conține, acestea sunt combinate, fiind incluse inițial opțiunile din activitate și ulterior acțiunile din fragmente, în ordinea în care acestea sunt declarate. De asemenea, se poate realiza și sortarea prin intermediul numărului de ordine definit de fiecare intrare propriu-zisă a meniului în parte.</​note>​ <note tip>În situația în care sunt definite meniuri atât pentru activitate cât și pentru fragmentele pe care le conține, acestea sunt combinate, fiind incluse inițial opțiunile din activitate și ulterior acțiunile din fragmente, în ordinea în care acestea sunt declarate. De asemenea, se poate realiza și sortarea prin intermediul numărului de ordine definit de fiecare intrare propriu-zisă a meniului în parte.</​note>​
Line 1167: Line 1182:
  
 ==== Tratarea evenimentelor asociate meniurilor ==== ==== Tratarea evenimentelor asociate meniurilor ====
 +
 Tratarea evenimentelor de accesare a unei intrări a meniului se face în cadrul metodei ''​onOptionsItemSelected(MenuItem)'',​ apelată în mod automat în momentul producerii unui astfel de eveniment. Aceasta primește ca parametru opțiunea din cadrul meniului care a fost aleasă de utilizator, recunoașterea sa realizându-se prin intermediul identificatorului unic asociat fiecărei intrări: Tratarea evenimentelor de accesare a unei intrări a meniului se face în cadrul metodei ''​onOptionsItemSelected(MenuItem)'',​ apelată în mod automat în momentul producerii unui astfel de eveniment. Aceasta primește ca parametru opțiunea din cadrul meniului care a fost aleasă de utilizator, recunoașterea sa realizându-se prin intermediul identificatorului unic asociat fiecărei intrări:
  
Line 1172: Line 1188:
 @Override @Override
 public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
-    ​switch(item.getItemId()) { +  ​switch(item.getItemId()) { 
-        case R.id.create:​ +    case R.id.create:​ 
-        case MENU_ID_CREATE:​ +    case MENU_ID_CREATE:​ 
-            // ... +      // ... 
-            return true; +      return true; 
-        // ...            +    // ...            
-    } +  } 
-    return super.onOptionsItemSelected(item);​+  return super.onOptionsItemSelected(item);​
 } }
 </​code>​ </​code>​
Line 1191: Line 1207:
 <code java> <code java>
 public class CustomMenuItemClickListener implements MenuItem.OnMenuItemClickListener { public class CustomMenuItemClickListener implements MenuItem.OnMenuItemClickListener {
-    ​@Override +  ​@Override 
-    public boolean onMenuItemClick(MenuItem item) { +  public boolean onMenuItemClick(MenuItem item) { 
-        switch(item.getItemId()) { +    switch(item.getItemId()) { 
-            case R.id.create:​ +      case R.id.create:​ 
-            case MENU_ID_CREATE:​ +      case MENU_ID_CREATE:​ 
-                // ... +        // ...
-                return true; +
-            // ...            +
-        }+
         return true;         return true;
 +      // ...           
     }     }
 +    return true;
 +  }
 } }
  
Line 1213: Line 1229:
  
 **2.** **utilizarea unei intenții asociate la o intrare din cadrul meniului** prin intermediul metodei ''​setIntent(Intent)'',​ lansându-se în execuție activitatea corespunzătoare în condițiile în care: **2.** **utilizarea unei intenții asociate la o intrare din cadrul meniului** prin intermediul metodei ''​setIntent(Intent)'',​ lansându-se în execuție activitatea corespunzătoare în condițiile în care:
-  * nu este suprascrisă metoda de tratare a evenimentului de selectare a unei intrări din cadrul meniului ''​onOptionsItemSelected()''​ +  * nu este suprascrisă metoda de tratare a evenimentului de selectare a unei intrări din cadrul meniului ''​onOptionsItemSelected()''​; 
-  * în situația în care metoda de tratare a evenimentului de selectare a unei intrări din cadrul meniului ''​onOptionsItemSelected()''​ este suprascrisă,​ trebuie să se apeleze metoda părinte (''​super.onOptionsItemSelected(menu)''​) pentru acele intrări ale meniului ce nu sunt procesate+  * în situația în care metoda de tratare a evenimentului de selectare a unei intrări din cadrul meniului ''​onOptionsItemSelected()''​ este suprascrisă,​ trebuie să se apeleze metoda părinte (''​super.onOptionsItemSelected(menu)''​) pentru acele intrări ale meniului ce nu sunt procesate.
  
 În mod implicit, nici o intrare din cadrul unui meniu nu are asociată o intenție. În mod implicit, nici o intrare din cadrul unui meniu nu are asociată o intenție.
Line 1221: Line 1237:
  
 === Meniuri contextuale === === Meniuri contextuale ===
 +
 Un //meniu contextual//​ (clasa [[http://​developer.android.com/​reference/​android/​view/​ContextMenu.html|ContextMenu]]) este asociat de regulă unui control din cadrul interfeței grafice (spre diferență de meniurile de opțiuni care sunt asociate activităților). De regulă, acesta este accesat la operația de apăsare prelungită pe obiectul respectiv (de tip ''​View''​),​ având aceeași structură ca orice meniu, metodele utilizate pentru construirea sa fiind aceleași. Un //meniu contextual//​ (clasa [[http://​developer.android.com/​reference/​android/​view/​ContextMenu.html|ContextMenu]]) este asociat de regulă unui control din cadrul interfeței grafice (spre diferență de meniurile de opțiuni care sunt asociate activităților). De regulă, acesta este accesat la operația de apăsare prelungită pe obiectul respectiv (de tip ''​View''​),​ având aceeași structură ca orice meniu, metodele utilizate pentru construirea sa fiind aceleași.
  
Line 1234: Line 1251:
 @Override @Override
 public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { public void onCreateContextMenu (ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-    ​super.onCreateContextMenu(menu,​ v, menuInfo);​ +  ​super.onCreateContextMenu(menu,​ v, menuInfo);​ 
-    // option 1 +  // option 1 
-    MenuInflater inflater = getMenuInflater();​ +  MenuInflater inflater = getMenuInflater();​ 
-    inflater.inflate(R.menu.context_menu,​ menu); +  inflater.inflate(R.menu.context_menu,​ menu); 
-    // option 2 +  // option 2 
-    menu.setHeaderTitle(R.string.operations);​ +  menu.setHeaderTitle(R.string.operations);​ 
-    menu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​+  menu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​
 } }
 </​code>​ Metoda primește următorii parametri (ce pot fi utilizați pentru a se determina ce obiect din cadrul interfeței grafice a fost accesat, pentru a se instanția meniul contextual corespunzător):​ </​code>​ Metoda primește următorii parametri (ce pot fi utilizați pentru a se determina ce obiect din cadrul interfeței grafice a fost accesat, pentru a se instanția meniul contextual corespunzător):​
-    * ''​menu''​ - meniul contextual care se dorește a fi afișat +    * ''​menu''​ - meniul contextual care se dorește a fi afișat; 
-    * ''​view''​ - elementul din cadrul interfeței grafice căruia îi este asociat meniul contextual +    * ''​view''​ - elementul din cadrul interfeței grafice căruia îi este asociat meniul contextual; 
-    * ''​menuInfo''​ - un obiect care oferă informații suplimentare cu privire la elementul selectat+    * ''​menuInfo''​ - un obiect care oferă informații suplimentare cu privire la elementul selectat.
   - implementarea metodei ''​onContextItemSelected(MenuItem)''​ care gestionează acțiunea de selectare a unei intrări din cadrul meniului contextual <code java>   - implementarea metodei ''​onContextItemSelected(MenuItem)''​ care gestionează acțiunea de selectare a unei intrări din cadrul meniului contextual <code java>
 @Override @Override
 public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
-    ​AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo)item.getMenuInfo();​ +  ​AdapterContextMenuInfo adapterContextMenuInfo = (AdapterContextMenuInfo)item.getMenuInfo();​ 
-    // or +  // or 
-    ExpandableContextMenuInfo expandableContextMenuInfo = (ExpandableContextMenuInfo)item.getMenuInfo();​ +  ExpandableContextMenuInfo expandableContextMenuInfo = (ExpandableContextMenuInfo)item.getMenuInfo();​ 
-    switch(item.getItemId()) { +  switch(item.getItemId()) { 
-        case R.id.create:​ +    case R.id.create:​ 
-        case MENU_ID_CREATE:​ +    case MENU_ID_CREATE:​ 
-            // ... +      // ... 
-            return true; +      return true; 
-        // ...            +    // ...            
-    } +  } 
-    return super.onContextItemSelected(item);​+  return super.onContextItemSelected(item);​
 } }
 </​code>​ Tratarea acțiunii de selectare a unei intrări din cadrul meniului contextual trebuie semnalată prin întoarcerea unui rezultat al metodei de tip ''​true'',​ în caz contrar trebuind apelată metoda părinte ''​super.onContextItemSelected(item)''​ care va determina apelarea metodelor corespunzătoare eventualelor fragmente pe care le poate conține activitatea (în ordinea în care acestea au fost declarate) până în momentul în care una dintre acestea va întoarce un rezultat (implementarea implicită a metodei întoarce ''​false''​ atât pentru clasa ''​Activity''​ cât și pentru clasa ''​Fragment''​). </​code>​ Tratarea acțiunii de selectare a unei intrări din cadrul meniului contextual trebuie semnalată prin întoarcerea unui rezultat al metodei de tip ''​true'',​ în caz contrar trebuind apelată metoda părinte ''​super.onContextItemSelected(item)''​ care va determina apelarea metodelor corespunzătoare eventualelor fragmente pe care le poate conține activitatea (în ordinea în care acestea au fost declarate) până în momentul în care una dintre acestea va întoarce un rezultat (implementarea implicită a metodei întoarce ''​false''​ atât pentru clasa ''​Activity''​ cât și pentru clasa ''​Fragment''​).
Line 1273: Line 1290:
 </​code>​ O activitate poate fi invocată prin intermediul unui meniu contextual, dacă specifică valorile respective în câmpul ce indică filtrul pentru intenții în fișierul ''​AndroidManifest.xml'':​ <code xml> </​code>​ O activitate poate fi invocată prin intermediul unui meniu contextual, dacă specifică valorile respective în câmpul ce indică filtrul pentru intenții în fișierul ''​AndroidManifest.xml'':​ <code xml>
 <​intent-filter>​ <​intent-filter>​
-   ... + ... 
-   ​<​category android:​name="​android.intent.category.ALTERNATIVE"​ /> + <​category android:​name="​android.intent.category.ALTERNATIVE"​ /> 
-   ​<​category android:​name="​android.intent.category.SELECTED_ALTERNATIVE"​ /> + <​category android:​name="​android.intent.category.SELECTED_ALTERNATIVE"​ /> 
-   ​...+ ...
 </​intent-filter>​ </​intent-filter>​
 </​code>​ </​code>​
   - căutarea unor activități care pot fi invocate folosind intenția respectivă prin intermediul metodei ''​Menu.addIntentOptions''​ (apelată pe obiectul transmis ca parametru metodei ''​onCreateOptionsMenu()''​) <code java>   - căutarea unor activități care pot fi invocate folosind intenția respectivă prin intermediul metodei ''​Menu.addIntentOptions''​ (apelată pe obiectul transmis ca parametru metodei ''​onCreateOptionsMenu()''​) <code java>
 menu.addIntentOptions( menu.addIntentOptions(
-    ​Menu.CATEGORY_ALTERNATIVE,​ // the group the contextual menu will be attached to +  ​Menu.CATEGORY_ALTERNATIVE,​ // the group the contextual menu will be attached to 
-    Menu.CATEGORY_ALTERNATIVE,​ // menu item ID for all of the menu items +  Menu.CATEGORY_ALTERNATIVE,​ // menu item ID for all of the menu items 
-    Menu.CATEGORY_ALTERNATIVE,​ // order number for each of the menu items +  Menu.CATEGORY_ALTERNATIVE,​ // order number for each of the menu items 
-    this.getComponentName(), ​  // the name of the current activity +  this.getComponentName(), ​  // the name of the current activity 
-    null,                      // no specific items to place with priority +  null,                      // no specific items to place with priority 
-    intent, ​                   // intent that can invoke the corresponding activities (previously defined) +  intent, ​                   // intent that can invoke the corresponding activities (previously defined) 
-    0,                         // no additional flags to manage the menu items +  0,                         // no additional flags to manage the menu items 
-    null); ​                    // no array of menu items to correlate with specific items+  null); ​                    // no array of menu items to correlate with specific items
 </​code>​ Metoda furnizează o listă de activități care corespund criteriilor precizate de intenție populând cu acestea intrările din cadrul meniului, în cadrul unui anumit grup, alocându-le identificatori și numere de ordine începând cu o anumită valoare.\\ Semnătura metodei este: <code java> </​code>​ Metoda furnizează o listă de activități care corespund criteriilor precizate de intenție populând cu acestea intrările din cadrul meniului, în cadrul unui anumit grup, alocându-le identificatori și numere de ordine începând cu o anumită valoare.\\ Semnătura metodei este: <code java>
 public abstract int addIntentOptions (int groupId, int itemId, int order, ComponentName caller, Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems) public abstract int addIntentOptions (int groupId, int itemId, int order, ComponentName caller, Intent[] specifics, Intent intent, int flags, MenuItem[] outSpecificItems)
Line 1308: Line 1325:
  
 El se distinge însă față de celelalte tipuri de meniuri, față de care ar părea să implementeze o funcționalitate comună: El se distinge însă față de celelalte tipuri de meniuri, față de care ar părea să implementeze o funcționalitate comună:
-  * spre diferență de meniurile de opțiuni, acesta este creat în mod manual și doar atunci când este accesat elementul căruia îi este atașat +  * spre diferență de meniurile de opțiuni, acesta este creat în mod manual și doar atunci când este accesat elementul căruia îi este atașat; 
-  * spre diferență de meniurile contextuale,​ acesta nu are nici un impact asupra controlului grafic căruia îi este atașat+  * spre diferență de meniurile contextuale,​ acesta nu are nici un impact asupra controlului grafic căruia îi este atașat;
  
 Un meniu de tip pop-up poate fi creat - ca orice meniu - atât prin intermediul unui fișier XML de resurse cât și programatic. Un meniu de tip pop-up poate fi creat - ca orice meniu - atât prin intermediul unui fișier XML de resurse cât și programatic.
Line 1317: Line 1334:
 public void showPopupMenu(View view) { public void showPopupMenu(View view) {
  
-    ​PopupMenu popupMenu = new PopupMenu(this,​ menu);+  ​PopupMenu popupMenu = new PopupMenu(this,​ menu);
     ​     ​
-    ​// option 1: defining a popup menu via a XML resource file+  ​// option 1: defining a popup menu via a XML resource file
     ​     ​
-        ​// android 3.0 +  ​// android 3.0 
-        MenuInflater menuInflater = popupMenu.getMenuInflater();​ +  MenuInflater menuInflater = popupMenu.getMenuInflater();​ 
-        menuInflater.inflate(R.menu.popup_menu,​ popupMenu.getMenu());​+  menuInflater.inflate(R.menu.popup_menu,​ popupMenu.getMenu());​
         ​         ​
-        ​// android 4.0 +  ​// android 4.0 
-        popupMenu.inflate(R.menu.popup_menu);​+  popupMenu.inflate(R.menu.popup_menu);​
         ​         ​
-    ​// option 2: defining a popup menu programatically +  ​// option 2: defining a popup menu programatically 
-    Menu menu = popupMenu.getMenu();​ +  Menu menu = popupMenu.getMenu();​ 
-    menu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​ +  menu.add(GROUP_ID_NONE,​ MENU_ID_CREATE,​ MENU_ORDER, R.string.create);​ 
-    // ...+  // ...
     ​     ​
-    ​popup.show();​+  ​popup.show();​
 } }
 </​code>​ </​code>​
Line 1347: Line 1364:
 <code java> <code java>
 popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
-                                         @Override +    ​@Override 
-                                         ​public boolean onMenuItemClick(MenuItem item) { +    public boolean onMenuItemClick(MenuItem item) { 
-                                             ​switch(item.getItemId()) { +      switch(item.getItemId()) { 
-                                                 ​case R.id.create:​ +        case R.id.create:​ 
-                                                 ​case MENU_ID_CREATE:​ +        case MENU_ID_CREATE:​ 
-                                                     ​// ... +          // ... 
-                                                     ​return true; +          return true; 
-                                                 ​// ...            +        // ...            
-                                             ​} +      } 
-                                             ​return true; +      return true; 
-                                         ​} +    } 
-                                     ​});+});
 </​code>​ </​code>​
  
Line 1365: Line 1382:
 Se dorește implementarea unei aplicații Android care să afișeze lista tuturor contactelor din agenda telefonică,​ împreună cu unele informații despre aceștia (imaginea asociată, numele, numărul de accesări, cea mai recentă accesare, apartenența la grupul de favoriți). De asemenea, în momentul în care este selectat un element din listă, se vor afișa toate numerele telefonice și toate adresele de poștă electronică stocate cu privire la acesta, împreună cu tipul lor. Totodată, va exista o facilitate de căutare pe măsură ce se introduce un șir de caractere, care poate fi regăsit în oricare dintre detaliile contactului respectiv. Se dorește implementarea unei aplicații Android care să afișeze lista tuturor contactelor din agenda telefonică,​ împreună cu unele informații despre aceștia (imaginea asociată, numele, numărul de accesări, cea mai recentă accesare, apartenența la grupul de favoriți). De asemenea, în momentul în care este selectat un element din listă, se vor afișa toate numerele telefonice și toate adresele de poștă electronică stocate cu privire la acesta, împreună cu tipul lor. Totodată, va exista o facilitate de căutare pe măsură ce se introduce un șir de caractere, care poate fi regăsit în oricare dintre detaliile contactului respectiv.
  
-{{ :​laboratoare:​laborator05:​addressbook.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​addressbook.png?​nolink&​400 }}
  
 **0.** Se recomandă ca în situația în care se folosește un emulator, să se adauge în aplicația //People// cel puțin două contacte care să poată fi gestionate prin intermediul aplicației. **0.** Se recomandă ca în situația în care se folosește un emulator, să se adauge în aplicația //People// cel puțin două contacte care să poată fi gestionate prin intermediul aplicației.
Line 1549: Line 1566:
   * adăugarea informațiilor referitoare la un contact (nume, numere de telefon, adrese de poștă electronică);​   * adăugarea informațiilor referitoare la un contact (nume, numere de telefon, adrese de poștă electronică);​
  
-{{ :​laboratoare:​laborator05:​insert_option.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​insert_option.png?​nolink&​400 }}
  
   * editarea informațiilor referitoare la un contact selectat în listă (nu va fi posibilă adăugarea de alte numere de telefon / adrese de poștă electronică);​   * editarea informațiilor referitoare la un contact selectat în listă (nu va fi posibilă adăugarea de alte numere de telefon / adrese de poștă electronică);​
  
-{{ :​laboratoare:​laborator05:​update_option.png?​nolink&​500 }}+{{ :​laboratoare:​laborator05:​update_option.png?​nolink&​400 }}
  
   * ștergerea informațiilor referitoare la un contact selectat în listă.   * ștergerea informațiilor referitoare la un contact selectat în listă.
Line 1675: Line 1692:
       return false;       return false;
     }     }
 +    FragmentManager fragmentManager = getFragmentManager();​
 +    ContactAdditionalDetailsFragment contactAdditionalDetailsFragment = (ContactAdditionalDetailsFragment)fragmentManager.findFragmentById(R.id.contact_additional_details);​
 +    if (contactAdditionalDetailsFragment != null) {
 +      FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();​
 +      fragmentTransaction.remove(contactAdditionalDetailsFragment);​
 +      fragmentTransaction.commit();​
 +      addressBookContactAdapter.setCheckedItemPosition(-1);​
 +    }     ​
     return true;     return true;
   }   }
Line 1681: Line 1706:
 </​code>​ </​code>​
  
-**7.** Să se realizeze o dispunere alternativă a listei de contacte din agenda telefonică,​ astfel încât pe rândurile pare respectiv pe rândurile impare, imaginea asociată unei persoane și pictograma indicând dacă aceasta a fost inclusă în lista de favoriți să apară dispuse în oglindă.+**7.** Să se realizeze o dispunere alternativă a listei de contacte din agenda telefonică,​ astfel încât pe rândurile pare respectiv pe rândurile impare, imaginea asociată unei persoane și pictograma indicând dacă aceasta a fost inclusă în lista de favoriți să fie aranjate invers. 
 + 
 +{{ :​laboratoare:​laborator05:​address_book_dispunere_alternativa.png?​nolink&​400 }}
  
   * în directorul ''​res/​layout''​ se vor defini două fișiere, ''​contact_view_odd.xml''​ și ''​contact_view_even.xml'',​ conținând cele două moduri de dispunere diferită;   * în directorul ''​res/​layout''​ se vor defini două fișiere, ''​contact_view_odd.xml''​ și ''​contact_view_even.xml'',​ conținând cele două moduri de dispunere diferită;
Line 1785: Line 1812:
 ===== Resurse Utile ===== ===== Resurse Utile =====
  
-[[http://​ptgmedia.pearsoncmg.com/​images/​9780321940261/​samplepages/​0321940261.pdf|Joseph ANNUZZI, Jr, Lauren DARCEY, Shane CONDER, Introduction to Android Application Development - Developer'​s Library, 4th Edition, Addison-Wesley,​ 2013]] - capitolul 8, subcapitolele ​//Using Container Control Classes//, capitolul 17, subcapitolul //​Menus//​\\ ​+[[http://​ptgmedia.pearsoncmg.com/​images/​9780321940261/​samplepages/​0321940261.pdf|Joseph ANNUZZI, Jr, Lauren DARCEY, Shane CONDER, Introduction to Android Application Development - Developer'​s Library, 4th Edition, Addison-Wesley,​ 2013]] - capitolul 8, subcapitolul ​//Using Container Control Classes//, capitolul 17, subcapitolul //​Menus//​\\ ​
 [[http://​www.bignerdranch.com/​we-write/​android-programming/​|Bill PHILLIPS, Brian HARDY, Android Programming. The Big Nerd Ranch Guide, Pearson Technology Group, 2013]] - capitolele 9, 16\\  [[http://​www.bignerdranch.com/​we-write/​android-programming/​|Bill PHILLIPS, Brian HARDY, Android Programming. The Big Nerd Ranch Guide, Pearson Technology Group, 2013]] - capitolele 9, 16\\ 
-[[http://​www.amazon.com/​Professional-Android-4-Application-Development/​dp/​1118102274|Reto MEIER, Professional Android for Application Development,​ John Wiley & Sons, 2012]] - capitolul ​4 (//The Android Widget Toolbok//, //​Introducing Adapters//​),​ 10 (//​Configuring Action Bar Icon Navigation Behavior//​)\\ ​+[[http://​www.amazon.com/​Professional-Android-4-Application-Development/​dp/​1118102274|Reto MEIER, Professional Android for Application Development,​ John Wiley & Sons, 2012]] - capitolele ​4 (//The Android Widget Toolbok//, //​Introducing Adapters//​),​ 10 (//​Configuring Action Bar Icon Navigation Behavior//​)\\ ​
 [[http://​books.google.ro/​books/​about/​The_Android_Developer_s_Cookbook.html?​id=Y4JR2yI2Fo0C&​redir_esc=y|Ronan SCHWARZ, Phil DUTSON, James STEELE, Nelson TO, Android Developer'​s Cookbook, Building Applications with the Android SDK, 2nd Edition, Addison Wesley, 2013]] - capitolele 6, 7\\  [[http://​books.google.ro/​books/​about/​The_Android_Developer_s_Cookbook.html?​id=Y4JR2yI2Fo0C&​redir_esc=y|Ronan SCHWARZ, Phil DUTSON, James STEELE, Nelson TO, Android Developer'​s Cookbook, Building Applications with the Android SDK, 2nd Edition, Addison Wesley, 2013]] - capitolele 6, 7\\ 
 [[http://​eu.wiley.com/​WileyCDA/​WileyTitle/​productCd-1118199545.html|Wei Meng LEE, Beginning Android 4 Application Development,​ Wiley, 2012]]\\ ​ [[http://​eu.wiley.com/​WileyCDA/​WileyTitle/​productCd-1118199545.html|Wei Meng LEE, Beginning Android 4 Application Development,​ Wiley, 2012]]\\ ​
laboratoare/laborator05.1427114798.txt.gz · Last modified: 2015/03/23 14:46 by Andrei Roșu-Cojocaru
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0