Differences

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

Link to this comparison view

eim:laboratoare:laborator03 [2017/03/10 06:10]
tmp.andrei.cojocaru
eim:laboratoare:laborator03 [2020/03/04 20:54] (current)
andrei.bolojan Change mimumum API level when creating project
Line 45: Line 45:
 </​code>​ </​code>​
  
-Atât mediul ​integrat de dezvoltare Android Studio ​cât și mediul integrat de dezvoltare Eclipse pun la dispoziția ​programatorilor ​atât un utilitar conținând biblioteci de controale, în care interfața grafică poate fi definită prin operații de tip drag-and-drop,​ cât și un editor text în care proprietățile acestor elemente pot fi specificate manual. Schimbările realizate într-una dintre aceste ferestre sunt transpuse automat și în cealaltă, astfel încât modificările din mediul vizual generează etichetele XML corespunzătoare,​ în timp ce efectul unor proprietăți stabilite în fișierul XML poate fi vizualizat imediat în editorul grafic.+Mediul ​integrat de dezvoltare Android Studio ​pune la dispoziția ​dezvoltatorilor ​atât un utilitar conținând biblioteci de controale, în care interfața grafică poate fi definită prin operații de tip drag-and-drop,​ cât și un editor text în care proprietățile acestor elemente pot fi specificate manual. Schimbările realizate într-una dintre aceste ferestre sunt transpuse automat și în cealaltă, astfel încât modificările din mediul vizual generează etichetele XML corespunzătoare,​ în timp ce efectul unor proprietăți stabilite în fișierul XML poate fi vizualizat imediat în editorul grafic.
  
 {{ :​eim:​laboratoare:​laborator03:​androidstudio_graphical_layout.png?​nolink&​650 }} {{ :​eim:​laboratoare:​laborator03:​androidstudio_graphical_layout.png?​nolink&​650 }}
  
-În **Android Studio**, utilitarul vizual poate fi accesat din panoul //Design//, putând fi specificate (prin selecția dintr-o listă) dispozitivul mobil pentru care se proiectează interfața grafică, orientarea ecranului (precum și alte moduri în care se poate găsi acesta), tema aplicației (stilul folosit), activitatea căreia îi este asociat, localizarea precum și nivelul de API.+Astfel, utilitarul vizual poate fi accesat din panoul //Design//, putând fi specificate (prin selecția dintr-o listă) dispozitivul mobil pentru care se proiectează interfața grafică, orientarea ecranului (precum și alte moduri în care se poate găsi acesta), tema aplicației (stilul folosit), activitatea căreia îi este asociat, localizarea precum și nivelul de API.
  
 +<​spoiler>​
 În cadrul bibliotecii de controale, organizarea elementelor grafice se face prin împărțirea lor în mai multe categorii: În cadrul bibliotecii de controale, organizarea elementelor grafice se face prin împărțirea lor în mai multe categorii:
-  * mecanisme de dispunere a conținutului (//​Layouts//​);​ 
   * forme de bază (//​Widgets//​);​   * forme de bază (//​Widgets//​);​
-  * câmpuri text (//Text Fields//);+  * câmpuri text (//Texts//); 
 +  * mecanisme de dispunere a conținutului (//Layouts//);
   * controale grafice ce pot conține alte componente(//​Containers//​);​   * controale grafice ce pot conține alte componente(//​Containers//​);​
-  * elemente pentru gestiunea datei calendaristice și a timpului (//​Date ​& Time//); +  ​* resurse multimedia (//​Images//​);​ 
-  * componente complexe de interacțiune cu utilizatorul (//Expert//); +  ​* elemente pentru gestiunea datei calendaristice și a timpului (//Date//); 
-  * obiecte definite de utilizator ​(//Custom//);+  * animații (//​Transitions//); 
 +  * componente complexe de interacțiune cu utilizatorul (//Advanced//​);​ 
 +  * componente Google (//​Google//​);​ 
 +  * elemente grafice definite în Material Design (//Design//); 
 +  * obiecte definite ​în bibliotecile ​de suport ​(//AppCompat//);
  
 Structura interfeței grafice (ierarhia de controale grafice) poate fi (pre)vizualizată,​ pentru fiecare obiect în parte indicându-se identificatorul său (dacă este definit) și tipul (între paranteze rotunde), în secțiunea //Component Tree//. Structura interfeței grafice (ierarhia de controale grafice) poate fi (pre)vizualizată,​ pentru fiecare obiect în parte indicându-se identificatorul său (dacă este definit) și tipul (între paranteze rotunde), în secțiunea //Component Tree//.
- 
-Pentru fiecare control grafic, atributele sale pot fi gestionate în secțiunea //​Properties//,​ fiind afișate toate proprietățile pe care le poate avea (proprii sau moștenite de la părinte), împreună cu valorile pe care le poate lua, utilizatorul putând alege dintre acestea. 
- 
-{{ :​eim:​laboratoare:​laborator03:​eclipse_graphical_layout.png?​nolink&​650 }} 
- 
-În **Eclipse**,​ utilitarul vizual poate fi accesat din panoul //Graphical Layout//, putând fi specificate (prin selecția dintr-o listă) dispozitivul mobil pentru care se proiectează interfața grafică, orientarea ecranului (precum și alte moduri în care se poate găsi acesta), tema aplicației (stilul folosit), activitatea căreia îî este asociat, localizarea precum și nivelul de API. 
- 
-În cadrul bibliotecii de controale, organizarea elementelor grafice se face prin împărțirea lor în mai multe categorii: 
-  * forme de bază (//Form Widgets//); 
-  * câmpuri text (//Text Fields//); 
-  * mecanisme de dispunere a conținutului (//​Layouts//​);​ 
-  * controale compuse (//​Composite//​);​ 
-  * componentele multimedia (//Images & Media//); 
-  * elemente pentru gestiunea datei calendaristice și a timpului (//Time & Date//); 
-  * tranziții (//​Transitions//​);​ 
-  * componente complexe de interacțiune cu utilizatorul (//​Advanced//​);​ 
-  * obiecte definite de utilizator (//Custom & Library Views//); 
- 
-Structura interfeței grafice (ierarhia de controale grafice) poate fi (pre)vizualizată în fereastra //​Outline//,​ pentru fiecare obiect în parte indicându-se identificatorul său (dacă este definit) și tipul (între paranteze rotunde). 
  
 Pentru fiecare control grafic, atributele sale pot fi gestionate în secțiunea //​Properties//,​ fiind afișate toate proprietățile pe care le poate avea (proprii sau moștenite de la părinte), împreună cu valorile pe care le poate lua, utilizatorul putând alege dintre acestea. Pentru fiecare control grafic, atributele sale pot fi gestionate în secțiunea //​Properties//,​ fiind afișate toate proprietățile pe care le poate avea (proprii sau moștenite de la părinte), împreună cu valorile pe care le poate lua, utilizatorul putând alege dintre acestea.
Line 141: Line 127:
  
 Elementele interfeței grafice sunt caracterizate prin anumite proprietăți,​ cum ar fi poziționarea,​ dimensiunile,​ conținutul pe care îl afișează, tipurile de date acceptate de la utilizator, informațiile ajutătoare. Fiecare parametru va fi indicat prin sintaxa ''​android:​proprietate="​valoare"''​ unde ''​proprietate''​ și ''​valoare''​ trebuie să respecte restricțiile definite în clasa ce descrie controlul respectiv. Elementele interfeței grafice sunt caracterizate prin anumite proprietăți,​ cum ar fi poziționarea,​ dimensiunile,​ conținutul pe care îl afișează, tipurile de date acceptate de la utilizator, informațiile ajutătoare. Fiecare parametru va fi indicat prin sintaxa ''​android:​proprietate="​valoare"''​ unde ''​proprietate''​ și ''​valoare''​ trebuie să respecte restricțiile definite în clasa ce descrie controlul respectiv.
 +</​spoiler>​
 ==== Dezvoltarea programatică a unei interfețe grafice ==== ==== Dezvoltarea programatică a unei interfețe grafice ====
  
 O interfață grafică poate fi definită și în codul sursă, într-un mod similar. Se creează inițial un obiect container (de tip ''​Layout'',​ derivat din ''​android.view.ViewGroup''​) care va cuprinde toate controalele,​ acesta fiind argumentul cu care va fi apelată metoda ''​setContentView()''​. ​ O interfață grafică poate fi definită și în codul sursă, într-un mod similar. Se creează inițial un obiect container (de tip ''​Layout'',​ derivat din ''​android.view.ViewGroup''​) care va cuprinde toate controalele,​ acesta fiind argumentul cu care va fi apelată metoda ''​setContentView()''​. ​
  
 +<​spoiler>​
 Pentru fiecare control vor fi specificate (manual, prin apelul metodei corespunzătoare) diferitele caracteristici,​ asociindu-i-se și un identificator (uzual, acesta poate fi orice număr întreg). Pentru fiecare proprietate a unui control grafic, sunt definite programatic metodele de tip getter și setter corespunzătoare. Pentru fiecare control vor fi specificate (manual, prin apelul metodei corespunzătoare) diferitele caracteristici,​ asociindu-i-se și un identificator (uzual, acesta poate fi orice număr întreg). Pentru fiecare proprietate a unui control grafic, sunt definite programatic metodele de tip getter și setter corespunzătoare.
  
Line 222: Line 209:
 } }
 </​file>​ </​file>​
 +</​spoiler>​
 ===== Controale în Android (widget-uri) ===== ===== Controale în Android (widget-uri) =====
  
Line 287: Line 274:
  
 Controlul de tip ''​TextView''​ este utilizat pentru afișarea unui text către utilizator, fără ca acesta să aibă posibilitatea de a-l modifica. ​ Controlul de tip ''​TextView''​ este utilizat pentru afișarea unui text către utilizator, fără ca acesta să aibă posibilitatea de a-l modifica. ​
 +
 +<​spoiler>​
  
 Conținutul pe care îl afișează un obiect ''​TextView''​ este indicat de proprietatea ''​text''​. De regulă, acesta referă o constantă definită în resursa care conține șirurile de caractere utilizate în cadrul aplicației. Gestiunea acestui atribut poate fi realizată prin metodele getter și setter respective. Conținutul pe care îl afișează un obiect ''​TextView''​ este indicat de proprietatea ''​text''​. De regulă, acesta referă o constantă definită în resursa care conține șirurile de caractere utilizate în cadrul aplicației. Gestiunea acestui atribut poate fi realizată prin metodele getter și setter respective.
Line 318: Line 307:
  
 În situația în care se dorește ca informația să fie afișată într-un mod care să o evidențieze,​ însă fără a permite utilizatorului să lanseze în execuție o altă activitate prin intermediul ei, se poate utiliza atributul ''​linksClickable''​ (având valoarea ''​false''​). În situația în care se dorește ca informația să fie afișată într-un mod care să o evidențieze,​ însă fără a permite utilizatorului să lanseze în execuție o altă activitate prin intermediul ei, se poate utiliza atributul ''​linksClickable''​ (având valoarea ''​false''​).
 +
 +</​spoiler>​
  
 === EditText === === EditText ===
Line 323: Line 314:
 ''​EditText''​ este o componentă utilizată pentru obținerea unui text de la utilizator. Implementarea sa pornește de la obiectul de tip ''​TextView'',​ astfel încât sunt moștenite toate proprietățile sale. ''​EditText''​ este o componentă utilizată pentru obținerea unui text de la utilizator. Implementarea sa pornește de la obiectul de tip ''​TextView'',​ astfel încât sunt moștenite toate proprietățile sale.
  
 +<​spoiler>​
 În mod obișnuit, valoarea introdusă va fi afișată doar pe o linie. Dacă se dorește redimensionarea controlului pe măsură ce este introdus un text de dimensiuni mai mari, va trebui specificată proprietatea ''​inputType="​textMultiLine"''​. De asemenea, se poate specifica explicit numărul de linii prin intermediul proprietății ''​lines''​ (în cazul în care aceasta nu este specificată,​ câmpul va fi redimensionat în mod automat pentru ca textul introdus să poată fi afișat; totuși indicarea acestui atribut este util pentru că impune o dimensiune fixă, utilizatorul având posibilitatea de a naviga în cadrul textului prin operația de derulare). În mod obișnuit, valoarea introdusă va fi afișată doar pe o linie. Dacă se dorește redimensionarea controlului pe măsură ce este introdus un text de dimensiuni mai mari, va trebui specificată proprietatea ''​inputType="​textMultiLine"''​. De asemenea, se poate specifica explicit numărul de linii prin intermediul proprietății ''​lines''​ (în cazul în care aceasta nu este specificată,​ câmpul va fi redimensionat în mod automat pentru ca textul introdus să poată fi afișat; totuși indicarea acestui atribut este util pentru că impune o dimensiune fixă, utilizatorul având posibilitatea de a naviga în cadrul textului prin operația de derulare).
  
Line 334: Line 326:
  
 Operația de tip apăsare lungă în cadrul unui control de tip ''​EditText''​ invocă meniul contextual, care oferă facilități pentru copierea unui text într-o / dintr-o zonă de memorie tampon (//eng.// copy-cut-paste),​ schimbarea mecanismului de introducere a textului, modificarea dicționarului ce conține cele mai frecvent folosite cuvinte. De asemenea, poate fi selectată (evidențiată) un fragment din textul respectiv (programatic,​ această funcționalitate poate fi obținută prin metodele ''​setSelection()''​ / ''​selectAll()''​). Operația de tip apăsare lungă în cadrul unui control de tip ''​EditText''​ invocă meniul contextual, care oferă facilități pentru copierea unui text într-o / dintr-o zonă de memorie tampon (//eng.// copy-cut-paste),​ schimbarea mecanismului de introducere a textului, modificarea dicționarului ce conține cele mai frecvent folosite cuvinte. De asemenea, poate fi selectată (evidențiată) un fragment din textul respectiv (programatic,​ această funcționalitate poate fi obținută prin metodele ''​setSelection()''​ / ''​selectAll()''​).
 +
 +</​spoiler>​
  
 === AutoCompleteTextView === === AutoCompleteTextView ===
Line 339: Line 333:
 Controlul de tip ''​AutoCompleteTextView''​ indică utilizatorului anumite valori cu care poate fi completat, în funcție de conținutul pe care acesta îl are acesta la un moment dat, pe baza unei liste de sugestii. Momentul la care sistemul de operare va oferi o sugestie este controlat prin intermediul proprietății ''​completionThreshold'',​ care indică numărul (minim) de caractere pe baza căruia se face potrivirea între șirul de caractere introdus de utilizator și valorile existente în lista de propuneri. Se poate afișa și un text sugestiv în cadrul listei de sugestii, prin proprietatea ''​completionHint''​. Controlul de tip ''​AutoCompleteTextView''​ indică utilizatorului anumite valori cu care poate fi completat, în funcție de conținutul pe care acesta îl are acesta la un moment dat, pe baza unei liste de sugestii. Momentul la care sistemul de operare va oferi o sugestie este controlat prin intermediul proprietății ''​completionThreshold'',​ care indică numărul (minim) de caractere pe baza căruia se face potrivirea între șirul de caractere introdus de utilizator și valorile existente în lista de propuneri. Se poate afișa și un text sugestiv în cadrul listei de sugestii, prin proprietatea ''​completionHint''​.
  
 +<​spoiler>​
 <code java> <code java>
 AutoCompleteTextView coursesAutoCompleteTextView = (AutoCompleteTextView)findViewById(R.id.courses_auto_complete_text_view);​ AutoCompleteTextView coursesAutoCompleteTextView = (AutoCompleteTextView)findViewById(R.id.courses_auto_complete_text_view);​
Line 351: Line 346:
  
 <​note>​Un astfel de control nu constrânge utilizatorul să introducă doar valori din lista de sugestii, conținutul controlului grafic putând fi oarecare.</​note>​ <​note>​Un astfel de control nu constrânge utilizatorul să introducă doar valori din lista de sugestii, conținutul controlului grafic putând fi oarecare.</​note>​
 +
 +</​spoiler>​
  
 === MultiAutoCompleteTextView === === MultiAutoCompleteTextView ===
Line 366: Line 363:
 O componentă de tip buton ce are atașat un text este definită de clasa ''​android.widget.Button'',​ fiind caracterizată prin proprietatea ''​text'',​ ce conține mesajul pe care acesta îl va afișa. O componentă de tip buton ce are atașat un text este definită de clasa ''​android.widget.Button'',​ fiind caracterizată prin proprietatea ''​text'',​ ce conține mesajul pe care acesta îl va afișa.
  
 +<​spoiler>​
 <note tip>În clasa ''​android.R.string''​ sunt definite mai multe constante care pot fi utilizate ca etichete pentru butoane (//OK//, //Cancel//, //Yes//, //​No//​).</​note>​ <note tip>În clasa ''​android.R.string''​ sunt definite mai multe constante care pot fi utilizate ca etichete pentru butoane (//OK//, //Cancel//, //Yes//, //​No//​).</​note>​
  
Line 381: Line 379:
  
 <note tip>În cazul folosirii de clase interne, membrii din clasa părinte ce se doresc a fi accesați trebuie să aibă imutabili (trebuie declarate cu atributul ''​final''​).</​note>​ <note tip>În cazul folosirii de clase interne, membrii din clasa părinte ce se doresc a fi accesați trebuie să aibă imutabili (trebuie declarate cu atributul ''​final''​).</​note>​
 +</​spoiler>​
  
 === ImageButton === === ImageButton ===
Line 386: Line 385:
 Un obiect de tip ''​ImageButton''​ (definit de clasa ''​android.widget.ImageButton''​) este utilizat pentru afişarea unei imagini, specificată în fişierul XML prin proprietatea ''​android:​src''​ sau programatic prin intermediul metodei ''​setImageResource()''​. Un obiect de tip ''​ImageButton''​ (definit de clasa ''​android.widget.ImageButton''​) este utilizat pentru afişarea unei imagini, specificată în fişierul XML prin proprietatea ''​android:​src''​ sau programatic prin intermediul metodei ''​setImageResource()''​.
  
 +<​spoiler>​
 <note tip>​Imaginea asociată unui buton de tip ''​ImageButton''​ este o resursă din directorul ''/​res/​drawable/''​ (accesibilă în XML prin adnotarea ''​@drawable/''​ sau programatic prin referinţa sa din clasa ''​R.drawable''​. </​note>​ <note tip>​Imaginea asociată unui buton de tip ''​ImageButton''​ este o resursă din directorul ''/​res/​drawable/''​ (accesibilă în XML prin adnotarea ''​@drawable/''​ sau programatic prin referinţa sa din clasa ''​R.drawable''​. </​note>​
  
Line 417: Line 417:
  
 <note important>​Ordinea elementelor în fișierul XML pentru realizarea selecției este important întrucât Android îl va verifica pe fiecare în parte pentru a vedea dacă acesta corespunde stării controlului. De aceea, imaginea pentru starea normală a controlului trebuie să se regăsească întotdeauna după toate celelalte cazuri particulare,​ în caz contrar aceasta fiind afișată întotdeauna de vreme ce nu impune nici o restricție asupra componentei.</​note>​ <note important>​Ordinea elementelor în fișierul XML pentru realizarea selecției este important întrucât Android îl va verifica pe fiecare în parte pentru a vedea dacă acesta corespunde stării controlului. De aceea, imaginea pentru starea normală a controlului trebuie să se regăsească întotdeauna după toate celelalte cazuri particulare,​ în caz contrar aceasta fiind afișată întotdeauna de vreme ce nu impune nici o restricție asupra componentei.</​note>​
 +</​spoiler>​
  
 === ToggleButton === === ToggleButton ===
Line 422: Line 423:
 Un obiect ''​ToggleButton''​ (definit de ''​android.widget.ToggleButton''​) este un tip de buton care are asociată o stare cu două valori (selectat și neselectat),​ asemenea unui checkbox sau radiobutton. Implicit, atunci când este selectat, acesta afișează o bară de culoare albastră în partea sa inferioară,​ iar atunci când nu este selectat, o bară de culoare gri.  Un obiect ''​ToggleButton''​ (definit de ''​android.widget.ToggleButton''​) este un tip de buton care are asociată o stare cu două valori (selectat și neselectat),​ asemenea unui checkbox sau radiobutton. Implicit, atunci când este selectat, acesta afișează o bară de culoare albastră în partea sa inferioară,​ iar atunci când nu este selectat, o bară de culoare gri. 
  
 +<​spoiler>​
 Textele afișate pentru valorile stărilor pot fi controlate în fișierul XML prin intermediul proprietăților ''​android:​textOn''​ respectiv ''​android:​textOff'',​ iar programatic prin metodele ''​setTextOn()''​ și ''​setTextOff()''​. Textele afișate pentru valorile stărilor pot fi controlate în fișierul XML prin intermediul proprietăților ''​android:​textOn''​ respectiv ''​android:​textOff'',​ iar programatic prin metodele ''​setTextOn()''​ și ''​setTextOff()''​.
  
Line 427: Line 429:
  
 <note tip>​Atributul ''​text'',​ moștenit de la obiectul de tip ''​Button'',​ nu este utilizat cu toate că poate fi definit.</​note>​ <note tip>​Atributul ''​text'',​ moștenit de la obiectul de tip ''​Button'',​ nu este utilizat cu toate că poate fi definit.</​note>​
 +</​spoiler>​
 === CheckBox === === CheckBox ===
  
Line 441: Line 443:
  
 Un element de tip ''​android.widget.RadioButton''​ este tot un buton cu două stări (selectat / neselectat),​ de obicei utilizat pentru selecția unei singure opțiuni dintr-o listă, excluderea mutuală fiind realizată prin includerea mai multor obiecte de acest tip într-o componentă de tip ''​android.widget.RadioGropup''​. ​ Un element de tip ''​android.widget.RadioButton''​ este tot un buton cu două stări (selectat / neselectat),​ de obicei utilizat pentru selecția unei singure opțiuni dintr-o listă, excluderea mutuală fiind realizată prin includerea mai multor obiecte de acest tip într-o componentă de tip ''​android.widget.RadioGropup''​. ​
 +<​spoiler>​
 <​note>​Un obiect de tip ''​RadioButton''​ se poate afla și în afara unui grup la fel cum un obiect de tip ''​RadioGroup''​ poate conține și alte controale decât butoane.</​note>​ <​note>​Un obiect de tip ''​RadioButton''​ se poate afla și în afara unui grup la fel cum un obiect de tip ''​RadioGroup''​ poate conține și alte controale decât butoane.</​note>​
  
Line 455: Line 457:
  
 În situația în care nu se dorește generarea unui eveniment de fiecare dată când se realizează o selecție, ci preluarea acesteia la un moment dat de timp ulterior, va fi utilizată metoda ''​getCheckedRadioButtonId()''​ din clasa ''​RadioGroup''​ care întoarce identificatorul butonului (din clasa ''​R.id''​) care a fost selectat (sau -1 dacă nu este selectat nici un buton radio din cadrul grupului). În situația în care nu se dorește generarea unui eveniment de fiecare dată când se realizează o selecție, ci preluarea acesteia la un moment dat de timp ulterior, va fi utilizată metoda ''​getCheckedRadioButtonId()''​ din clasa ''​RadioGroup''​ care întoarce identificatorul butonului (din clasa ''​R.id''​) care a fost selectat (sau -1 dacă nu este selectat nici un buton radio din cadrul grupului).
 +</​spoiler>​
  
-==== Controale de tip multimedia ====+==== Controale de tip multimedia ​-- Opțional ​====
  
 Android pune la dispoziția utilizatorilor mai multe controale pentru redarea conținuturilor de tip multimedia, dintre care cele mai folosite sunt ''​ImageView''​ (pentru imagini) și ''​VideoView''​ (pentru conținut video). Android pune la dispoziția utilizatorilor mai multe controale pentru redarea conținuturilor de tip multimedia, dintre care cele mai folosite sunt ''​ImageView''​ (pentru imagini) și ''​VideoView''​ (pentru conținut video).
Line 469: Line 472:
     * programatic,​ folosind una din metodele     * programatic,​ folosind una din metodele
       * ''​setImageResource()'',​ care primește ca parametru identificatorul resursei din clasa ''​R.drawable''​       * ''​setImageResource()'',​ care primește ca parametru identificatorul resursei din clasa ''​R.drawable''​
-      * ''​setImageBitmap()'',​ ce primește un parametru de tip ''​Bitmap''​ încărcat din resursa respectivă,​ ulterior putând fi realizate și unele modificări <code java>+      * ''​setImageBitmap()'',​ ce primește un parametru de tip ''​Bitmap''​ încărcat din resursa respectivă,​ ulterior putând fi realizate și unele modificări ​ 
 +<​spoiler>​ 
 +<code java>
 ImageView someImageView = (ImageView)findViewById(R.id.some_image_view);​ ImageView someImageView = (ImageView)findViewById(R.id.some_image_view);​
 Bitmap someBitmap = BitmapFactory.decodeResource(this.getResources(),​ R.drawable.some_image);​ Bitmap someBitmap = BitmapFactory.decodeResource(this.getResources(),​ R.drawable.some_image);​
Line 484: Line 489:
  
 Pentru un astfel de obiect pot fi precizate parametrii precum lățimea și înălțimea maximă (''​maxWidth'',​ respectiv ''​maxHeight''​),​ precum și mecanismul folosit pentru scalarea conținutului în situația în care suprafața pe care se realizează afișarea este diferită de dimensiunile reale ale resursei (''​scaleType''​). Pentru un astfel de obiect pot fi precizate parametrii precum lățimea și înălțimea maximă (''​maxWidth'',​ respectiv ''​maxHeight''​),​ precum și mecanismul folosit pentru scalarea conținutului în situația în care suprafața pe care se realizează afișarea este diferită de dimensiunile reale ale resursei (''​scaleType''​).
 +</​spoiler>​
 === VideoView === === VideoView ===
  
 Controlul de tip ''​VideoView''​ este utilizat pentru redarea de conținut video, într-unul din formatele ''​H.263'',​ ''​H.264 AVC'',​ ''​MPEG-4 SP''​ sau ''​VP8''​. Controlul de tip ''​VideoView''​ este utilizat pentru redarea de conținut video, într-unul din formatele ''​H.263'',​ ''​H.264 AVC'',​ ''​MPEG-4 SP''​ sau ''​VP8''​.
  
 +<​spoiler>​
 Conținutul acestui control poate fi specificat prin una din metodele ''​setVideoPath(String)''​ sau ''​setVideoUri(Uri)'',​ prin care se indică locația unui fișier stocat pe dispozitiv sau aflat la distanță, pe un server. Conținutul acestui control poate fi specificat prin una din metodele ''​setVideoPath(String)''​ sau ''​setVideoUri(Uri)'',​ prin care se indică locația unui fișier stocat pe dispozitiv sau aflat la distanță, pe un server.
  
Line 536: Line 542:
 Controalele obiectului ''​MediaController''​ pot fi afișate sau nu prin metodele ''​show(int timeout)''​ respectiv ''​hide()''​. Controalele obiectului ''​MediaController''​ pot fi afișate sau nu prin metodele ''​show(int timeout)''​ respectiv ''​hide()''​.
  
-==== Controale pentru gestiunea datei calendaristice și a timpului ​====+</​spoiler>​ 
 + 
 +<​spoiler ​Controale pentru gestiunea datei calendaristice și a timpului ​-- facultativ>​
  
 Majoritatea bibliotecilor de controale pun la dispoziția dezvoltatorilor componente pentru gestiunea informațiilor legate de data calendaristică și timp. În Android, cele mai frecvent uzitate elemente de acest tip sunt ''​DatePicker'',​ ''​TimePicker'',​ ''​AnalogClock''​ și ''​DigitalClock''​. Majoritatea bibliotecilor de controale pun la dispoziția dezvoltatorilor componente pentru gestiunea informațiilor legate de data calendaristică și timp. În Android, cele mai frecvent uzitate elemente de acest tip sunt ''​DatePicker'',​ ''​TimePicker'',​ ''​AnalogClock''​ și ''​DigitalClock''​.
Line 542: Line 550:
 {{ :​eim:​laboratoare:​laborator03:​date_time_samples.png?​nolink&​300 }} {{ :​eim:​laboratoare:​laborator03:​date_time_samples.png?​nolink&​300 }}
  
-=== DatePicker ​===+**DatePicker** 
  
 Obiectul de tip ''​DatePicker''​ este folosit pentru gestiunea componentelor unei date calendaristice (zi, lună, an). Obiectul de tip ''​DatePicker''​ este folosit pentru gestiunea componentelor unei date calendaristice (zi, lună, an).
Line 554: Line 562:
 Valorile pe care le poate lua acest element pot fi controlate prin intermediul proprietăților ''​minDate''​ (respectiv ''​minYear''​) și ''​maxDate''​ (respectiv ''​maxYear''​). De asemenea, dacă se dorește sau nu afișarea unui calendar va fi indicat prin intermediul proprietății ''​calendarViewShown''​. Valorile pe care le poate lua acest element pot fi controlate prin intermediul proprietăților ''​minDate''​ (respectiv ''​minYear''​) și ''​maxDate''​ (respectiv ''​maxYear''​). De asemenea, dacă se dorește sau nu afișarea unui calendar va fi indicat prin intermediul proprietății ''​calendarViewShown''​.
  
-=== TimePicker ​===+**TimePicker** 
  
 Obiectul de tip ''​TimePicker''​ este folosit pentru gestiunea componentelor timpului (oră, minut). Obiectul de tip ''​TimePicker''​ este folosit pentru gestiunea componentelor timpului (oră, minut).
Line 564: Line 572:
 Conținutul controlului se obține prin metodele ''​getCurrentHour()'',​ respectiv ''​getCurrentMinute()''​. ​ Conținutul controlului se obține prin metodele ''​getCurrentHour()'',​ respectiv ''​getCurrentMinute()''​. ​
  
-=== AnalogClock ​===+ **AnalogClock** 
  
 Obiectul de tip ''​AnalogClock''​ este folosit pentru afișarea timpului curent, folosind un ceas analogic. Utilizatorul nu poate interacționa cu un astfel de control, actualizarea conținutului său fiind realizată în mod automat, la fiecare minut. ​ Obiectul de tip ''​AnalogClock''​ este folosit pentru afișarea timpului curent, folosind un ceas analogic. Utilizatorul nu poate interacționa cu un astfel de control, actualizarea conținutului său fiind realizată în mod automat, la fiecare minut. ​
Line 570: Line 578:
 <note tip>Un obiect de tip ''​AnalogClock''​ poate fi particularizat în sensul că se pot specifica anumite resurse grafice pentru afișarea cadranului orar și a limbilor care indică ora și minutul.</​note>​ <note tip>Un obiect de tip ''​AnalogClock''​ poate fi particularizat în sensul că se pot specifica anumite resurse grafice pentru afișarea cadranului orar și a limbilor care indică ora și minutul.</​note>​
  
-=== DigitalClock (nivel API < 17) ===+ DigitalClock (nivel API < 17) 
  
 Obiectul de tip ''​DigitalClock''​ este folosit pentru afișarea timpului curent, folosind un ceas digital. Este un control de tip  ''​TextView''​ de la care moștenește toate funcționalitățile. Utilizatorul nu poate interacționa cu un astfel de control, actualizarea conținutului său fiind realizată în mod automat, la fiecare secundă. Obiectul de tip ''​DigitalClock''​ este folosit pentru afișarea timpului curent, folosind un ceas digital. Este un control de tip  ''​TextView''​ de la care moștenește toate funcționalitățile. Utilizatorul nu poate interacționa cu un astfel de control, actualizarea conținutului său fiind realizată în mod automat, la fiecare secundă.
  
-=== TextClock (nivel API >= 17) ===+ TextClock (nivel API >= 17)
  
 Obiectul de tip ''​TextClock''​ este folosit pentru afișarea datei calendaristice și/sau a timpului curent (folosind formatul 12/24 ore și permițând schimbarea zonei de timp). ​ Obiectul de tip ''​TextClock''​ este folosit pentru afișarea datei calendaristice și/sau a timpului curent (folosind formatul 12/24 ore și permițând schimbarea zonei de timp). ​
Line 580: Line 588:
 Implicit, acest control nu afișează și secundele. Implicit, acest control nu afișează și secundele.
  
-=== Chronometer ​===+ Chronometer ​
  
 Un obiect de tip ''​Chronometer''​ este utilizat pentru monitorizarea timpului scurs începând de la un anumit moment, pentru activitățile în care un astfel de element este esențial. Un obiect de tip ''​Chronometer''​ este utilizat pentru monitorizarea timpului scurs începând de la un anumit moment, pentru activitățile în care un astfel de element este esențial.
Line 593: Line 601:
 Monitorizarea evenimentelor legate de un obiect de tip ''​Chronometer''​ se face prin implementarea unui obiect ascultător de tip ''​Chronometer.OnChronometerTickListener''​ prin (re)definirea metodei ''​onChronometerTick()''​. Monitorizarea evenimentelor legate de un obiect de tip ''​Chronometer''​ se face prin implementarea unui obiect ascultător de tip ''​Chronometer.OnChronometerTickListener''​ prin (re)definirea metodei ''​onChronometerTick()''​.
  
-==== Controale pentru monitorizarea progresului ​====+</​spoiler>​ 
 +<​spoiler ​Controale pentru monitorizarea progresului ​-- facultativ>​
  
 În momentul în care sunt realizate acțiuni care durează o perioadă de timp mai mare, o practică uzuală este de a indica utilizatorului faptul că un proces este în desfășurare și că aplicația nu s-a blocat prin intermediu unei bare de progres. O altă situație în care se dorește să se afișeze progresul este indicarea evoluției pe care a realizat-o un utilizator în cadrul unei aplicații (rularea unui fișier multimedia - timp scurs vs. timp rămas, nivelul la care s-a ajuns în cadrul unui joc) sau chiar controlul acestei poziții. În momentul în care sunt realizate acțiuni care durează o perioadă de timp mai mare, o practică uzuală este de a indica utilizatorului faptul că un proces este în desfășurare și că aplicația nu s-a blocat prin intermediu unei bare de progres. O altă situație în care se dorește să se afișeze progresul este indicarea evoluției pe care a realizat-o un utilizator în cadrul unei aplicații (rularea unui fișier multimedia - timp scurs vs. timp rămas, nivelul la care s-a ajuns în cadrul unui joc) sau chiar controlul acestei poziții.
Line 601: Line 610:
 {{ :​eim:​laboratoare:​laborator03:​progress_monitoring_samples.png?​nolink&​600 }} {{ :​eim:​laboratoare:​laborator03:​progress_monitoring_samples.png?​nolink&​600 }}
  
-=== ProgressBar ​===+ **ProgressBar** 
  
 Obiectul de tip ''​ProgressBar''​ are mai multe forme: Obiectul de tip ''​ProgressBar''​ are mai multe forme:
Line 644: Line 653:
   * prin invocarea metodei ''​setProgressBarIndeterminateVisibility()''​.   * prin invocarea metodei ''​setProgressBarIndeterminateVisibility()''​.
  
-=== SeekBar ​===+ **SeekBar** 
  
 În situația în care se dorește să se ofere utilizatorului posibilitatea de a controla progresul unei anumite operații, se folosește un obiect de tip ''​SeekBar'',​ care are în plus un selector a cărui locație poate fi modificată manual prin interfața grafică, la orice poziție cuprinsă între ''​0''​ și valoarea indicată de proprietatea ''​max''​. În situația în care se dorește să se ofere utilizatorului posibilitatea de a controla progresul unei anumite operații, se folosește un obiect de tip ''​SeekBar'',​ care are în plus un selector a cărui locație poate fi modificată manual prin interfața grafică, la orice poziție cuprinsă între ''​0''​ și valoarea indicată de proprietatea ''​max''​.
Line 664: Line 673:
 </​code>​ </​code>​
  
-==== Alte Tipuri de Controale Grafice ​====+ **Alte Tipuri de Controale Grafice** -- facultativ  ​
  
 {{ :​eim:​laboratoare:​laborator03:​other_controls_samples.png?​nolink&​300 }} {{ :​eim:​laboratoare:​laborator03:​other_controls_samples.png?​nolink&​300 }}
  
-=== NumberPicker ​===+ **NumberPicker** 
  
 Un obiect de tip ''​NumberPicker''​ este folosit pentru a alege o valoare dintr-un interval definit de proprietățile ''​min''​ și ''​max''​. Forma în care este afișat depinde de tema pe care o folosește aplicația: Un obiect de tip ''​NumberPicker''​ este folosit pentru a alege o valoare dintr-un interval definit de proprietățile ''​min''​ și ''​max''​. Forma în care este afișat depinde de tema pe care o folosește aplicația:
Line 678: Line 687:
 Identificarea momentului în care a fost modificată o valoare poate fi realizată prin implementarea unui obiect ascultător de tip ''​NumberPicker.OnValueChangeListener''​ și rederinirea valorii ''​onValueChange()''​. Identificarea momentului în care a fost modificată o valoare poate fi realizată prin implementarea unui obiect ascultător de tip ''​NumberPicker.OnValueChangeListener''​ și rederinirea valorii ''​onValueChange()''​.
  
-=== RatingBar ​===+ **RatingBar** 
  
 Un obiect de tip ''​RatingBar''​ este utilizat pentru a gestiona calificative,​ exprimate sub formă de număr de stele. Definirea unui astfel de obiect implică: Un obiect de tip ''​RatingBar''​ este utilizat pentru a gestiona calificative,​ exprimate sub formă de număr de stele. Definirea unui astfel de obiect implică:
Line 685: Line 694:
  
 Evenimentele reprezentate de interacțiunea cu utilizatorul sunt gestionate prin intermediul unui obiect ascultător de tip ''​RatingBar.OnRatingBarChangeListener''​ și (re)definirea metodei ''​onRatingChanged()'',​ apelată în momentul în care a fost înregistrată o modificare a calificativului (în timpul selecției propriu-zise a valorii nu se invocă metoda). Evenimentele reprezentate de interacțiunea cu utilizatorul sunt gestionate prin intermediul unui obiect ascultător de tip ''​RatingBar.OnRatingBarChangeListener''​ și (re)definirea metodei ''​onRatingChanged()'',​ apelată în momentul în care a fost înregistrată o modificare a calificativului (în timpul selecției propriu-zise a valorii nu se invocă metoda).
 +</​spoiler>​
  
-===== Mecanisme pentru dispunerea controalelor (layout) ====+==== Mecanisme pentru dispunerea controalelor (layout) ​-- obligatoriu ​====
 Controalele Android fac parte din cadrul unui grup (obiect de tip ''​android.view.ViewGroup''​) care definește și modul în care acestea sunt dispuse în cadrul interfeței grafice precum și dimensiunile pe care le pot lua, motiv pentru care o astfel de componentă este referită și sub denumirea de layout. Acest element nu vizează însă tratarea evenimentelor legate de interacțiunea cu utilizatorul. Controalele Android fac parte din cadrul unui grup (obiect de tip ''​android.view.ViewGroup''​) care definește și modul în care acestea sunt dispuse în cadrul interfeței grafice precum și dimensiunile pe care le pot lua, motiv pentru care o astfel de componentă este referită și sub denumirea de layout. Acest element nu vizează însă tratarea evenimentelor legate de interacțiunea cu utilizatorul.
  
Line 726: Line 735:
   * ''​textColor''​ indică culoarea textului în format ''#​rrggbb''​ (sau ''#​aarrggbb''​),​ putând fi referită și o culoare definită anterior într-un fișier ''​colors.xml''​ (sau cu orice altă denumire) din directorul ''/​res/​values''​ în care elementul rădăcină este ''<​resources>''​ (elementele de aici fiind referite prin ''​@color/​...''​).   * ''​textColor''​ indică culoarea textului în format ''#​rrggbb''​ (sau ''#​aarrggbb''​),​ putând fi referită și o culoare definită anterior într-un fișier ''​colors.xml''​ (sau cu orice altă denumire) din directorul ''/​res/​values''​ în care elementul rădăcină este ''<​resources>''​ (elementele de aici fiind referite prin ''​@color/​...''​).
  
-==== LinearLayout ====+==== LinearLayout ​(obligatoriu) ​====
  
 În cadrul unui grup de tip ''​LinearLayout'',​ componentele sunt dispuse fie pe orizontală,​ fie pe verticală, în funcție de  proprietatea ''​orientation''​ (putând lua valorile ''​horizontal''​ - implicită sau ''​vertical''​). În cadrul unui grup de tip ''​LinearLayout'',​ componentele sunt dispuse fie pe orizontală,​ fie pe verticală, în funcție de  proprietatea ''​orientation''​ (putând lua valorile ''​horizontal''​ - implicită sau ''​vertical''​).
  
 +<​spoiler>​
 <code xml> <code xml>
 <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​ <​LinearLayout xmlns:​android="​http://​schemas.android.com/​apk/​res/​android"​
Line 750: Line 760:
  
 {{ :​eim:​laboratoare:​laborator03:​linear_layout_vertical_sample.png?​nolink&​300 }} {{ :​eim:​laboratoare:​laborator03:​linear_layout_vertical_sample.png?​nolink&​300 }}
 +</​spoiler>​
 ==== AbsoluteLayout ==== ==== AbsoluteLayout ====
  
Line 774: Line 784:
 ''​FrameLayout''​ reprezintă o strategie de poziționare folosită pentru afișarea unei singure componente la un moment dat. Totuși, aceasta poate fi populată cu mai multe elemente grafice, recomandându-se ca doar una singură să fie vizibilă. Vizibilitatea poate fi specificată în fișierul XML prin proprietatea ''​android:​visibility''​ care poate lua valorile ''​visible''​ sau ''​gone'',​ respectiv programatic,​ folosind metoda ''​setVisibility()''​ ce primește ca parametru constantele ''​View.VISIBLE''​ sau ''​View.GONE''​. De regulă, afișarea unei componente este realizată în mod dinamic, ca rezultat al unei metode de tratare a unui eveniment. ''​FrameLayout''​ reprezintă o strategie de poziționare folosită pentru afișarea unei singure componente la un moment dat. Totuși, aceasta poate fi populată cu mai multe elemente grafice, recomandându-se ca doar una singură să fie vizibilă. Vizibilitatea poate fi specificată în fișierul XML prin proprietatea ''​android:​visibility''​ care poate lua valorile ''​visible''​ sau ''​gone'',​ respectiv programatic,​ folosind metoda ''​setVisibility()''​ ce primește ca parametru constantele ''​View.VISIBLE''​ sau ''​View.GONE''​. De regulă, afișarea unei componente este realizată în mod dinamic, ca rezultat al unei metode de tratare a unui eveniment.
  
 +<​spoiler>​
 <note tip>​Dimensiunea obiectului de tip ''​FrameLayout''​ ar trebui să fie preluată de la controlul cel mai voluminos, riscându-se altfel ca pe măsură ce se afișează elemente de dimensiuni mai mari, acestea să nu fie vizibile în totalitate. În acest scop, se va folosi proprietatea XML ''​android:​measureAllChildren="​true"''​ sau se va apela metoda ''​setMeasureAllChildren(true)'',​ astfel încât să se realizeze redimensionarea continer-ului la toate elementele conținute, nu doar la cele vizibile la un moment dat.</​note>​ <note tip>​Dimensiunea obiectului de tip ''​FrameLayout''​ ar trebui să fie preluată de la controlul cel mai voluminos, riscându-se altfel ca pe măsură ce se afișează elemente de dimensiuni mai mari, acestea să nu fie vizibile în totalitate. În acest scop, se va folosi proprietatea XML ''​android:​measureAllChildren="​true"''​ sau se va apela metoda ''​setMeasureAllChildren(true)'',​ astfel încât să se realizeze redimensionarea continer-ului la toate elementele conținute, nu doar la cele vizibile la un moment dat.</​note>​
  
Line 785: Line 796:
  
 {{ :​eim:​laboratoare:​laborator03:​frame_layout_sample.png?​nolink&​300 }} {{ :​eim:​laboratoare:​laborator03:​frame_layout_sample.png?​nolink&​300 }}
 +</​spoiler>​
 ==== TableLayout ==== ==== TableLayout ====
  
 Într-un mecanism de poziționare de tip ''​TableLayout'',​ elementele componente (layout-uri sau widget-uri) sunt plasate în cadrul unui tabel, fără ca marginile să fie afișate și fără a se specifica în mod explicit numărul de rânduri sau de coloane, acestea fiind determinate în mod automat (numărul de rânduri este determinat ca sumă a elementelor de tip ''​TableRow'',​ iar numărul de coloane ca maximul numărului de componente de pe o linie; de asemenea, dimensiunea unei coloane este dată de componenta cea mai voluminoasă afișată în cadrul ei). Într-un mecanism de poziționare de tip ''​TableLayout'',​ elementele componente (layout-uri sau widget-uri) sunt plasate în cadrul unui tabel, fără ca marginile să fie afișate și fără a se specifica în mod explicit numărul de rânduri sau de coloane, acestea fiind determinate în mod automat (numărul de rânduri este determinat ca sumă a elementelor de tip ''​TableRow'',​ iar numărul de coloane ca maximul numărului de componente de pe o linie; de asemenea, dimensiunea unei coloane este dată de componenta cea mai voluminoasă afișată în cadrul ei).
  
 +<​spoiler>​
 Cele mai importante proprietăți ale unui layout de acest tip sunt: Cele mai importante proprietăți ale unui layout de acest tip sunt:
   * ''​stretchColumns''​ - specifică o listă de indecși indicând coloanele care ar trebui mărite în cazul în care tabelul este mai mic decât spațiul de afișare pe care îl pune la dispoziție;​   * ''​stretchColumns''​ - specifică o listă de indecși indicând coloanele care ar trebui mărite în cazul în care tabelul este mai mic decât spațiul de afișare pe care îl pune la dispoziție;​
Line 859: Line 871:
  
 {{ :​eim:​laboratoare:​laborator03:​table_layout_sample.png?​nolink&​300 }} {{ :​eim:​laboratoare:​laborator03:​table_layout_sample.png?​nolink&​300 }}
 +</​spoiler>​
  
 ==== GridLayout ==== ==== GridLayout ====
Line 864: Line 877:
 Layout-ul de tip ''​GridLayout''​ este utilizat tot pentru dispunerea componentelor într-un format tabelar, folosind însă o sintaxă mult mai flexibilă. Totodată, acest mecanism este și mult mai eficient din punctul de vedere al randării. Layout-ul de tip ''​GridLayout''​ este utilizat tot pentru dispunerea componentelor într-un format tabelar, folosind însă o sintaxă mult mai flexibilă. Totodată, acest mecanism este și mult mai eficient din punctul de vedere al randării.
  
 +<​spoiler>​
 Astfel, pentru specificarea numărului de rânduri și de coloane se vor utiliza proprietățile ''​rowCount''​ și ''​columnCount'',​ indicându-se pentru fiecare element grafic în parte poziția la care va fi plasat, prin atributele ''​layout_row''​ și ''​layout_column''​. În cazul în care pentru o componentă grafică nu se specifică linia sau coloana din care face parte, atributul ''​orientation''​ (având va valori posibile ''​horizontal''​ sau ''​vertical''​ indică dacă elementul următor va fi plasat pe linia sau pe coloana succesivă). Astfel, pentru specificarea numărului de rânduri și de coloane se vor utiliza proprietățile ''​rowCount''​ și ''​columnCount'',​ indicându-se pentru fiecare element grafic în parte poziția la care va fi plasat, prin atributele ''​layout_row''​ și ''​layout_column''​. În cazul în care pentru o componentă grafică nu se specifică linia sau coloana din care face parte, atributul ''​orientation''​ (având va valori posibile ''​horizontal''​ sau ''​vertical''​ indică dacă elementul următor va fi plasat pe linia sau pe coloana succesivă).
  
Line 873: Line 887:
  
 {{ :​eim:​laboratoare:​laborator03:​grid_layout_sample.png?​nolink&​600 }} {{ :​eim:​laboratoare:​laborator03:​grid_layout_sample.png?​nolink&​600 }}
 +</​spoiler>​
 ==== ScrollView ==== ==== ScrollView ====
  
Line 880: Line 894:
 ===== Adaptarea interfeței grafice în funcție de orientarea ecranului ===== ===== Adaptarea interfeței grafice în funcție de orientarea ecranului =====
  
-Dispozitivele Android suportă două moduri de orientare a ecranului: ''​portrait''​ și ''​landscape''​. În momentul în care se produce o modificare a orientării dispozitivului de afișare, activitatea care rulează în mod curent este distrusă și apoi recreată. Aplicațiile trebuie să gestioneze astfel de situații, adaptând interfața grafică în funcție de suprafața de care dispun. În acest scop, poate fi adoptată una din următoarele abordări:+Dispozitivele Android suportă două moduri de orientare a ecranului: ''​portrait''​ și ''​landscape''​. În momentul în care se produce o modificare a orientării dispozitivului de afișare, activitatea care rulează în mod curent este distrusă și apoi recreată. Aplicațiile trebuie să gestioneze astfel de situații, adaptând interfața grafică în funcție de suprafața de care dispun. ​ 
 + 
 +<​spoiler>​ 
 +În acest scop, poate fi adoptată una din următoarele abordări:
   - **ancorarea** elementelor grafice (de regulă, de cele patru colțuri ale ecranului), folosind o dispunere de tip ''​RelativeLayout''​ împreună cu o combinație a proprietăților ''​layout_alignParentTop'',​ ''​layout_alignParentBottom'',​ ''​layout_alignParentLeft'',​ ''​layout_alignParentRight'',​ ''​layout_centerHorizontal'',​ ''​layout_centerVertical''​   - **ancorarea** elementelor grafice (de regulă, de cele patru colțuri ale ecranului), folosind o dispunere de tip ''​RelativeLayout''​ împreună cu o combinație a proprietăților ''​layout_alignParentTop'',​ ''​layout_alignParentBottom'',​ ''​layout_alignParentLeft'',​ ''​layout_alignParentRight'',​ ''​layout_centerHorizontal'',​ ''​layout_centerVertical''​
   - **redimensionarea și repoziționarea**   - **redimensionarea și repoziționarea**
Line 910: Line 927:
  
 Pentru optimizarea unei interfețe grafice pot fi utilizate și alte utilitare cum ar fi //Hierarchy View// sau [[http://​developer.android.com/​tools/​debugging/​improving-w-lint.html|Lint]]. Pentru optimizarea unei interfețe grafice pot fi utilizate și alte utilitare cum ar fi //Hierarchy View// sau [[http://​developer.android.com/​tools/​debugging/​improving-w-lint.html|Lint]].
 +</​spoiler>​
 ===== Activitate de Laborator ===== ===== Activitate de Laborator =====
  
 Se dorește implementarea unei aplicații Android, conținând o singură activitate, care să ofere utilizatorilor funcționalitatea necesară pentru formarea unui număr de telefon (PhoneDialer). Se dorește implementarea unei aplicații Android, conținând o singură activitate, care să ofere utilizatorilor funcționalitatea necesară pentru formarea unui număr de telefon (PhoneDialer).
  
 +{{ :​eim:​laboratoare:​laborator03:​phonedialer_portrait.png?​nolink&​300 }}
  
 **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator03'​. Acesta trebuie să conțină unui fișier ''​README.md'',​ un fișier ''​.gitignore''​ specific unei aplicații Android și un fișier ''​LICENSE''​ care să descrie condițiile pentru utilizarea aplicației. **1.** În contul Github personal, să se creeze un depozit denumit '​Laborator03'​. Acesta trebuie să conțină unui fișier ''​README.md'',​ un fișier ''​.gitignore''​ specific unei aplicații Android și un fișier ''​LICENSE''​ care să descrie condițiile pentru utilizarea aplicației.
Line 923: Line 941:
  
 **2.** Să se cloneze într-un director de pe discul local conținutul depozitului la distanță astfel creat. În urma acestei operații, directorul Laborator03 va trebui să se conțină fișierele ''​README.md'',​ ''​.gitignore''​ care indică tipurile de fișiere (extensiile) ignorate și ''​LICENSE''​. <​code>​ **2.** Să se cloneze într-un director de pe discul local conținutul depozitului la distanță astfel creat. În urma acestei operații, directorul Laborator03 va trebui să se conțină fișierele ''​README.md'',​ ''​.gitignore''​ care indică tipurile de fișiere (extensiile) ignorate și ''​LICENSE''​. <​code>​
-student@eim2017:~$ git clone https://​www.github.com/​perfectstudent/​Laborator03.git+student@eg106:~$ git clone https://​www.github.com/​perfectstudent/​Laborator03.git
 </​code>​ </​code>​
  
-**3.** În directorul Laborator03 de pe discul local, să se creeze un proiect ​Eclipse ​denumit //​PhoneDialer//​ (se selectează //File// → //New// → //​Project//,​ iar apoi //Android ​Application Project//).+**3.** În directorul Laborator03 de pe discul local, să se creeze un proiect ​Android Studio ​denumit //​PhoneDialer//​ (se selectează //Start a new Android ​Studio project//).
  
-{{ :​eim:​laboratoare:​laborator03:​eclipse01.png?​nolink&​400 }}+{{ :​eim:​laboratoare:​laborator03:​androidstudio01.png?​nolink&​600 }}
  
 Se indică detaliile proiectului:​ Se indică detaliile proiectului:​
-  * **Application ​Name** - //Phone Dialer// +  * **Application ​name** - //Phone Dialer// 
-  * **Project Name** - //PhoneDialer// +  * **Company domain** - //lab03.eim.systems.cs.pub.ro// (se va genera în mod automat ​**Package ​name** cu valoarea //ro.pub.cs.systems.eim.lab03.phonedialer//
-  * **Package ​Name** - ''​ro.pub.cs.systems.eim.lab03.phonedialer''​ +  * **Project location** - locația directorului de pe discul local unde a fost descărcat depozitul la distanță //​Laborator03//​
-  * **Minimum Required SDK** - API 16: Android 4.1 (Jelly Bean+
-  * **Target SDK** - API 16: Android 4.1 (Jelly Bean) +
-  * **Compile With** - API 16: Android 4.1 (Jelly Bean) +
-  * **Theme** - Holo Light with Dark Action Bar+
  
-{{ :​eim:​laboratoare:​laborator03:​eclipse02.png?​nolink&​400 }}+{{ :​eim:​laboratoare:​laborator03:​androidstudio02.png?​nolink&​600 }}
  
-Vor fi precizate și alte detalii legate de configurare:​+Se indică platforma pentru care se dezvoltă aplicația Android (se bifează doar //Phone and Tablet//), iar SDK-ul Android (minim) pentru care se garantează funcționarea este API 24 (Nougat, 7.0).
  
-Procesul de configurare a proiectului implică și precizarea următoarelor informații: +{{ :eim:​laboratoare:​laborator03:​androidstudio03.png?​nolink&​600 }}
-  * necesitatea de a se crea o pictogramă implicită pentru aplicația aferentă proiectului;​ +
-  * necesitatea de a se crea o activitate (corespunzătoare unei ferestre a aplicației aferente proiectului);​ +
-  * caracterul de bibliotecă al proiectului;​ +
-  * locația la care va fi plasat proiectul (în spațiul de lucru sau nu); +
-  * atașarea proiectului la o zonă de lucru+
  
-{{ :eim:​laboratoare:​laborator03:​eclipse03.png?​nolink&​400 }}+Se creează o activitate care inițial nu va conține nimic (//Empty Activity//):
  
-În privința pictogramei asociate proiectului Android, se păstrează configurația implicită:+{{ :eim:​laboratoare:​laborator03:​androidstudio04.png?​nolink&​600 }}
  
-{{ :eim:​laboratoare:​laborator03:​eclipse04.png?​nolink&​400 }}+pentru care se precizează:
  
-Se creează o activitate ​care inițial nu va conține nimic: +  * **Activity Name** (denumirea activității) - ''​PhoneDialerActivity'';​ 
- +  * **Layout Name** (denumirea fișierului XML din ''​res/​layout''​ în care va fi construită interfața grafică) - ''​activity_phone_dialer.xml''​.
-{{ :​eim:​laboratoare:​laborator03:​eclipse05.png?​nolink&​400 }} +
- +
-pentru care se precizează:​+
  
-  ​denumirea activității - ''​PhoneDialerActivity''​+De asemeena: 
-  * denumirea fișierului XML din ''​res/​layout''​ în care va fi construită interfațgrafică - ''​activity_phone_dialer''​.+  ​se bifează opțiunea de a se genera în mod automat fișierul XML care conține descrierea interfeței grafice (//Generate Layout File//)
 +  * folosirea claselor ​din bibliotecile de suport ​care asigură posibilitatea de folosire ​unor funcționalități din SDK-uri mai recente pe dispozitive mobile cu nivele de API mai vechi (//​Backwards Compatibility (AppCompat)//​).
  
-{{ :​eim:​laboratoare:​laborator03:​eclipse06.png?​nolink&​400 }}+{{ :​eim:​laboratoare:​laborator03:​androidstudio05.png?​nolink&​600 }}
  
 **4.** În fișierul ''​activity_phone_dialer''​ din directorul ''​res/​layout''​ se construiește interfața grafică folosind: **4.** În fișierul ''​activity_phone_dialer''​ din directorul ''​res/​layout''​ se construiește interfața grafică folosind:
-  * editorul vizual (//Graphical Layout//) +  * editorul vizual (//Design//) 
-  * editorul XML (manual)+  * editorul XML (//Text//)
  
 Aceasta va conține: Aceasta va conține:
Line 985: Line 992:
   * pentru butoanele ce conțin cifre sau caracterele ''​*''​ / ''#'',​ se va adăuga simbolul corespunzător la numărul de telefon care se dorește format;   * pentru butoanele ce conțin cifre sau caracterele ''​*''​ / ''#'',​ se va adăuga simbolul corespunzător la numărul de telefon care se dorește format;
   * pentru butonul de corecție, se va șterge ultimul caracter (în cazul în care numărul de telefon nu este vid);   * pentru butonul de corecție, se va șterge ultimul caracter (în cazul în care numărul de telefon nu este vid);
-  * pentru butonul de apel, se va invoca intenția care realizează legătura telefonică <code java> +  * pentru butonul de apel, se va invoca intenția care realizează legătura telefonică; întrucât se compilează proiectul Android folosind o versiune mai mare decât Marshmelow (6.0), este necesar să fie solicitată permisiunea de efectuare a apelului telefonic la momentul rulării: ​<code java> 
-Intent intent = new Intent(Intent.ACTION_CALL);​ +if (ContextCompat.checkSelfPermission(PhoneDialerActivity.this,​ Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { 
-intent.setData(Uri.parse("​tel:"​+phoneNumber)); +  ActivityCompat.requestPermissions( 
-startActivity(intent);​+    PhoneDialerActivity.this,​ 
 +    new String[]{Manifest.permission.CALL_PHONE},​ 
 +    Constants.PERMISSION_REQUEST_CALL_PHONE);​ 
 +} else { 
 +  ​Intent intent = new Intent(Intent.ACTION_CALL);​ 
 +  intent.setData(Uri.parse("​tel:"​ + phoneNumberEditText.getText().toString())); 
 +  startActivity(intent);​ 
 +}
 </​code>​ </​code>​
 <note tip>​Pentru a putea apela, în fișierul ''​AndroidManifest.xml''​ trebuie să se specifice o permisiune explicită în acest sens:\\ ''<​uses-permission android:​name="​android.permission.CALL_PHONE"​ />''</​note>​ <note tip>​Pentru a putea apela, în fișierul ''​AndroidManifest.xml''​ trebuie să se specifice o permisiune explicită în acest sens:\\ ''<​uses-permission android:​name="​android.permission.CALL_PHONE"​ />''</​note>​
Line 1020: Line 1034:
 {{ :​eim:​laboratoare:​laborator03:​phonedialer_landscape.png?​nolink&​600 }} {{ :​eim:​laboratoare:​laborator03:​phonedialer_landscape.png?​nolink&​600 }}
  
-În Eclipse Mars 1 (4.5.1), se creează un nou subdirector ''​layout-land''​ în directorul ''​res''​ (din meniul contextual afișat cu right click, se selectează //New// → //Folder//, indicându-se ​locația la care se dorește să fie plasat și denumirea sa):+În Android Studio, se creează un nou subdirector ''​layout-land''​ în directorul ''​res''​ (din meniul contextual afișat cu right click, se selectează //New// → //Android resource directory//, indicându-se ​denumirea sa (''​layout-land''​),​ tipul de resursă (''​layout''​) și setul codului sursă pentru ​care se definește resursa respectivă (''​main''​)): 
 + 
 +{{ :​eim:​laboratoare:​laborator03:​androidstudio06.png?​nolink&​600 }} 
 + 
 +{{ :​eim:​laboratoare:​laborator03:​androidstudio07.png?​nolink&​600 }}
  
-{{ :eim:​laboratoare:​laborator03:​eclipse07.png?​nolink&​400 }}+Se trece în modul de vizualizare //Project// și în directorul ''​res/​layout-land''​ se copiază conținutul fișierului ''​activity_phone.dialer.xml''​ prin operații de tip copy-paste și se realizează modificările necesare SAU se poate preciza un fișier nou cu aceeași denumire:
  
-{{ :​eim:​laboratoare:​laborator03:​eclipse08.png?​nolink&​400 }}+{{ :​eim:​laboratoare:​laborator03:​androidstudio08.png?​nolink&​600 }}
  
-Ulterior se copiază conținutul fișierului ''​activity_phone.dialer.xml''​ prin operații de tip copy-paste și se realizează modificările necesare.+{{ :​eim:​laboratoare:​laborator03:​androidstudio09.png?nolink }}
  
 **7.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator03'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​ **7.** ​ Să se încarce modificările realizate în cadrul depozitului '​Laborator03'​ de pe contul Github personal, folosind un mesaj sugestiv. <​code>​
-student@eim2017:​~/​Laborator03$ git add PhoneDialer/​* +student@eg106:​~/​Laborator03$ git add PhoneDialer/​* 
-student@eim2017:​~/​Laborator03$ git commit -m "​implemented taks for laboratory 03" +student@eg106:​~/​Laborator03$ git commit -m "​implemented taks for laboratory 03" 
-student@eim2017:​~/​Laborator03$ git push origin master+student@eg106:​~/​Laborator03$ git push origin master
 </​code>​ </​code>​
  
eim/laboratoare/laborator03.1489119019.txt.gz · Last modified: 2017/03/10 06:10 by tmp.andrei.cojocaru
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0