Sunteți pe pagina 1din 113

Android

Android este creat de Google, pentru dispozitivele mobile


(smartphone, tablete, reader, auto, tv, wear – ex. ceas, etc.).
Cuprinde:
 sistem de operare,
 middleware,
 aplicaţii de bază (client de e-mail, program de SMS, calendar,
hărţi, browser, agendă pentru date de contact, etc.).

http://developer.android.com/index.html

Aplicaţiile pentru Android sunt scrise folosind limbajul de


programare Java.
Pentru a rula aplicaţii scrise pentru Android pe un alt sistem de
operare este nevoie de o VM maşină virtuală Dalvik.

1
Clasele sunt compilate în Java şi apoi transformate folosind aplicaţia
dx în fişiere executabile Dalvik (.dex).

2
Arhitectura SO Android

3
4
Necesităţi software
 JDK – pentru compilarea claselor Java
http://www.oracle.com/technetwork/java/javase/downloads/index.htm
l

 Android Studio– pentru compilarea în pachete Android și rularea


http://developer.android.com/sdk/index.html

 API – documentaţia claselor Android


http://developer.android.com/reference/classes.html

5
Varianta 1 - Android Studio – IDE care cuprinde:
o Editor de cod
o Dispozitive virtuale
o Android SDK Tools
o Android Platform-tools
o Gradle – creează multiple aplicații folosind același proiect

Varianta 2 - Eclipse – dezvoltarea s-a oprit la sfârșitul anului 2015


o Eclipse for Mobile Developers
http://www.eclipse.org/downloads/

o ADT Plugin for Eclipse


http://developer.android.com/sdk/eclipse-adt.html

6
Android SDK (Software Development Kit)
 compilează codul unei aplicaţii într-un pachet Android, care este o
arhivă cu extensia .apk, care apoi poate fi instalată pe orice
dispozitiv care rulează Android.
 Include un emulator de dispozitiv mobil virtual AVD (Android
Virtual Device) care rulează pe computer. Emulatorul permite
dezvoltarea şi testarea aplicaţiilor Android fără a fi nevoie de
dispozitivul fizic. Interacţiunea cu emulatorul se realizează prin
mouse (în loc de touchscreen-ul dispozitivului) şi taste (în loc de
butoane).

 Android SDK are un manager prin care se pot instala documentaţii


şi alte pachete.

 Din Android SDK Manager se instalează o versiune de Android.

7
8
 Trebuiesc instalate minim:
o Android SDK Tools
o Android SDK Platform-tools
o Android SDK Build-tools
În folderul Android X.X trebuiesc instalate cel puțin:
o SDK Platform
o Emulator system (exemplu, Google APIs Intel x86 Atom_64
System Image)

AVD Manager – se creează un dispozitiv cu anumite caracteristici


hardware, care apoi se porneşte cu Start.
Cerințe procesor 64 biți.
Nu suportă: WiFi, Bluetooth, NFC, Sd card, headphones, Usb.

9
10
11
12
Alternativa emulatoarelor puse la dispoziție de Android Studio sunt
(mai rapide, dedicate pentru jocuri):
 Genymotion
 Windroy
 AMIDuOS
 Droid4X
 ANDY
 ARChon
 Bluestacks
 Remix OS Player
 KoPlayer
 Memu

13
14
15
GUI pentru aplicații mobile
De urmărit următoarele aspecte:

 Gestionarea evenimentelor
 Componentele arată ca și cum produc evenimente la atingere
 Evenimentele sunt tratate conform specificațiilor
 Icon-urile sunt sugestive

 Manager de poziționare și modele de navigare – layout


 Pentru utilizator trebuie să fie clar unde se află în cadrul
aplicației
 Să fie ușor de navigat înapoi (ex., back button, swipe)
 Să fie ușor de revenit la ecranul principal

16
 Animații
 Tranzițiile dintre ecrane dau senzația de ecran temporar
 Demonstrează tranziții între stări sau încărcarea unor stări
 Asigură feedback la acțiunile utilizatorilor

Android a introdus conceptul de MaterialDesign care s-a inspirat din


principiile designului print-based (hârtie și cerneală):

https://material.io/guidelines/material-design/introduction.html

17
Se poate face un prototip al interfeței grafice utilizator:
 Fără detalii – desen de mână, util pentru design, comunicare
concept, obținere feedback asupra funcțiilor de bază, fără animații
și layout.
 Detaliat – folosește o aplicație (ex., Photoshop – design visual
components, Invision – simulate basic interactions), are definite
layout și interacțiuni, aproape de forma finală, util pentru
implementare, feedback detaliat.

18
Crearea unui proiect Android în AndroidStudio
 În Android Studio - File – New – New Project
 Project Name - este numele proiectului
 Build Target – este versiunea de Android SDK în care va fi
compilat proiectul
 Application Name – numele aplicaţiei care va apare pe
dispozitivul mobil
 Company domain – un nume care va fi adăugat la numele
pachetului în care va fi salvat proiectul. Are aceeaşi structură ca
la Java. Folderul src – conţine fişierele sursă java. Numele
pachetului declarat iniţial trebuie să fie format din cel puţin 2
module separate prin punct.

19
20
Main Activity – se creează automat clasa de bază, subclasă a clasei
AppCompatActivity, care va rula aplicaţia. În această clasă este
rescrisă metoda onCreate(...) unde trebuie făcute toate iniţializările,
inclusiv interfaţa grafică.

21
Cum se schimbă versiunea API pentru un proiect
Meniul File – Project Structure
În stânga se alege SDK Location și în dreapta se setează Android
SDK location

Cum se schimbă versiunea API pentru mai multe proiecte


Se închide proiectul curent din File – Close project
În fereastra următoare se alege: Configure – Project Defaults – Project
Structure – se setează Android SDK location

În proiect se deschide fișierul app – build.gradle și se setează:


compileSdkVersion 26
targetSdkVersion 26
dependencies {
compile 'com.android.support:appcompat-
v7:27.0.2'
}
22
Detalii:
https://developer.android.com/about/versions/oreo/android-8.0-
migration.html

23
24
Exemplu-Android Studio-PrimaAplicatie
Afişează un text pe ecranul dispozitivului mobil. Codul java se află în
fişierul din:
C:\...\PrimaAplicatie\app\src\main\java\devicesscreens\com\example\
primaaplicatie

package devicesscreens.com.example.primaaplicatie;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
25
Layout-ul (manager de poziționare) se află în fişierul:
\PrimaAplicatie\app\src\main\res\layout\activity_main.xml

Acest fişier poate fi vizualizat în AndroidStudio sub formă de layout


sau cod xml (se alege din partea de jos a ferestrei).

<?xml version="1.0" encoding="utf-8"?>


<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"

tools:context="devicesscreens.com.example.primaaplicatie.Main
Activity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
26
android:text="@string/eticheta1"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.165"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

Șiruri de caractere folosite în proiect se află în fişierul:


\PrimaAplicatie\app\src\main\res\values\strings.xml

<resources>
<string name="app_name">PrimaAplicatie</string>
<string name="eticheta1">Sir de afisat in eticheta
</string>
</resources>

27
28
29
Android GUI
Pentru crearea unei aplicaţii Android cu GUI se folosesc una din
clasele:
 View – componente – conţine subclase pentru implementarea
componentelor grafice (widgets) (de exemplu, butoane, etichete,
câmpuri text). O clasă descendentă din View descrie o structură de
date care memorează proprietăţi de desenare-vizualizare, layout,
evenimente (tastatură, scroll, touchpad).
 ViewGroup – containere – conţine subclase pentru managementul
poziţiei componentelor grafice (layout), care implementează
arhitecturi diferite cu aspect liniar, relativ sau tabelar. O astfel de
clasă hotărăşte dimensiunea şi aranjarea componentelor grafice
descendente din ea.

30
Caracteristicile aplicaţiilor GUI pentru Android:
 Fiecare aplicaţie rulează într-un proces separat, care este o instanţă a
Dalvik VM.
 Trebuie să aibă definită o ierarhie de activităţi, în fişierul
AndroidManifest.xml, care se găseşte în directorul proiectului.
 Se foloseşte metoda setContentView() cu referinţă la nodul rădăcină
pentru a adăuga o activitate unui layout.
 Pentru fiecare nouă activitate, se apelează metoda setContentView(),
pentru ca aceasta să devină activă.
31
 Este important să se urmărească toate ferestrele instanţiate, deoarece
acestea trebuie închise cu metoda finish().
 Toate obiectele de tip View au asociat un ID cu ajutorul căruia se
face referire la componenta grafică respectivă. Toate ID-urile sunt
salvate în fişierul R.java, care nu poate fi modificat manual (au doar
câmpuri membre finale).
 ..\app\build\generatedJava\_namespaced_r_class_sources\R.java
 Centrul axelor de coordonate este stânga sus.
 Unitatea de măsură pentru componente este pixel-ul.
 Componentele grafice au asociate evenimente, care pot fi ascultate
cu ascultători.
 Clasa View are o serie de metode pentru tratarea evenimentelor:
o onKeyDown(int, KeyEvent) - apăsare de tastă
o onKeyUp(int, KeyEvent) - ridicare de tastă
o onTrackballEvent(MotionEvent) - mişcare TrackBall
o onTouchEvent(MotionEvent) - mişcare pe TouchScreen
32
 Aplicaţiile GUI pot fi create în două moduri:
o Cod sursă într-un fişier Java
o Cod xml în fişiere situate în directorul res al proiectului. În
fişierele xml pot fi setate proprietăţile componentelor grafice.
Este încurajată crearea layout-ului prin cod xml.

33
Layout (manager de poziționare) - introducere
 Se defineşte într-un fişier XML.
 Elementele din Xml sunt asemănătoare cu funcţionalităţile claselor
Java.
 Pentru crearea acestui fişier se poate folosi un vocabular Xml (de
exemplu, cel din Studio), dar pot fi folosite şi alte aplicaţii IDE
pentru crearea layout-ului (exemplu, DroidDraw).
 Layout-ul poate fi creat prin drag-and-drop de componente grafice
în modul layout şi modificarea proprietăţilor în cod xml. Orice
modificare făcută într-un mod de vizualizare (layout sau cod xml) va
fi operată în fişier.

34
 Există o serie de aplicaţii care permit crearea de wireframe (schema
interfeţei grafice: elemente de interfaţă, navigarea, cu accent pe
funcţionalitate şi comportament şi nu pe stil, culori, grafică).
App Inventor
http://www.appinventorbeta.com/about/

35
Fişierul /R.java
Conţine o listă cu toate resursele folosite în proiect (layout, id-uri,
string-uri).
Această clasă este generată automat, folosind aplicaţia Ant, atunci
când se alege comanda „build”.

Are clase finale imbricate pentru toate tipurile de resurse folosite în


proiect.

36
package android.support.coreui;

public final class R {


public static final class attr {
public static final int font = 0x7f020070;
public static final int fontStyle = 0x7f020078;

}
âpublic static final class bool {
public static final int
abc_action_bar_embed_tabs = 0x7f030000;
}
public static final class color {
public static final int
notification_icon_bg_color = 0x7f04003f;
}
public static final class dimen {
public static final int
37
compat_button_inset_horizontal_material =
0x7f05004a;
public static final int
compat_button_inset_vertical_material = 0x7f05004b;
public static final int
}
public static final class id {
public static final int action_container =
0x7f07000e;
public static final int action_divider =
0x7f070010;
}
public static final class string {
public static final int
status_bar_notification_info_overflow = 0x7f0b0021;
}
}

38
XML - eXtensible Markup Language
 este un limbaj care structurează, memorează, transportă date şi nu
are ca scop afişarea acestora (cum face Html).
 Un fişier xml conţine tag-uri (elemente/ noduri).
 Element: <nume_tag>…</nume_tag>

 Numele unui element trebuie să înceapă cu o literă şi nu conţine


spaţii. Dacă este format din mai multe cuvinte este indicat să se
folosească _
 Un element poate conţine:
o date sub formă de text,
o alte elemente,
o atribute.
 Fiecare fişier xml trebuie să aibă un nod rădăcină, care va fi
părintele tuturor celorlalte noduri.
 Se formează un arbore de noduri, care porneşte de la nodul rădăcină.
39
 Reguli de creare a unui fişier xml:
o Fiecare nod trebuie să aibă un tag de închidere (</numeTag>)
o Tag-urile sunt CaseSensitive
o Elementele xml trebuie corect imbricate
o Un element poate să aibă atribute (de exemplu, <string
name="hello">, în care name este atributul elementului string).
Un atribut poate fi transformat în element (de preferat),
deoarece un element nu poate conţine valori multivaloare, nu
poate implementa o structură arborescentă, nu sunt uşor de
extins.
o Valorile atributelor trebuie puse în ” ”.
o Comentarii: <!-- comentariu -->
o Mai multe caractere spaţiu sunt tratate ca şi cum ar fi unul
singur
o Linie nouă: LF

40
o Caractere speciale în xml:
&lt ; <
&gt; >
&amp; &
&apos; '
&quot; "
 Tag-urile nu sunt predefinite în limbajul xml. Din acest motiv în
Android s-a definit un vocabular xml pentru a emula lucrul cu
clasele şi obiectele.
 Xml este descriptiv şi nu se poate obţine cod executabil direct din
xml.
 <?xml version="1.0" encoding="utf-8"?> - prima linie dintr-un
fişier xml este o declaraţie a versiunii de xml folosite şi tipului de
codare (UTF-8 este o codificare de caractere pe 8biţi pentru Unicode
– codificarea folosită în Java).

41
http://developer.android.com/guide/topics/ui/index.html
http://developer.android.com/guide/topics/fundamentals.html

42
Unitățile de măsură
pentru imagini sunt:
 dp – unitate de măsură abstractă care se bazează pe densitatea
ecranului (Density-independent Pixel). Pentru un ecran de 160 dpi
(dots per inch) 1dp=1px
 in – (inch) = 25.4 mm dimensiune fizică
 mm – (milimetri) dimensiune fizică
 pt – (points) = 1/72 inch
 px – (pixels) este dependentă de dimensiunea fizică a ecranului
 sp – unitate de măsură abstractă scalară folosită pentru fonturi
(Scale-independent Pixel), care permite adaptarea la densitatea
ecranului și preferințele utilizatorului.

43
Drawable
Există în fiecare proiect (din Android 1.6) mai multe directoare
drawable, fiecare corespunzător pentru diferite rezoluţii (dpi - dots per
inch). Acestea sunt necesare pentru a crea aplicaţii pentru ecrane de
dimensiuni şi rezoluţii diferite. Rezoluţia în dpi este o măsură a
clarităţii unei imagini şi exprimă câte puncte pot să încapă într-un inch
(1 inch = 2.54cm). Dimensiunea punctului depinde de fiecare
echipament în parte.

44
În fișierele xml fișierele icon se trec fără extensie, astfel:
<item
android:icon="@drawable/ic_action_edit" >
 Directoarele drawable corespunzătoare diferitelor rezoluții nu sunt
specificate în fișierele xml. De exemplu, mai sus nu se trece:
<item
android:icon="@drawable-hdpi/ic_action_edit" >

45
Adaptare la diferite ecrane
Un proiect poate proiectat să arate diferit corespunzător diverselor
dispozitive mobile, cu dimensiuni diferite. Astfel, se poate adapta
organizarea și dimensiunea componentelor grafice la dimensiunile
spațiului de afișare.
Ecranele dispozitivelor mobile se caracterizează prin:
 dimensiune (screen_size: small, normal, large, xlarge). Pentru
fiecare dimensiune trebuie creat un fișier layout.xml (cu același
nume) în directorul:
res/layout-<screen_size>
 densitate (density : low (ldpi), medium (mdpi), high (hdpi), extra
high (xhdpi)).

Dimensiunea absolută a ecranului nu este importantă.


46
Importantă este organizarea componentelor grafice în layout.
https://developer.android.com/guide/topics/resources/providing-
resources.html#BestMatch
Pentru ecran, implicit se consideră orientarea Portrait.
Pentru orientarea Landscape se creează directorul layout-land
MyProject/ res/
layout/ # default (portrait)
main.xml
layout-land/ # landscape
main.xml
layout-large/ # large (portrait)
main.xml
layout-large-land/ # large landscape
main.xml
https://developer.android.com/training/multiscreen/index.html

47
Adăugarea unor imagini diferite pentru diferite setări de limbă se face
introducând fișiere imagine cu același nume în directoarele fiecărei
limbi:

MyProject/ res/
mipmap/ # default (Engleza)
fisier_imagine.jpg/png/bmp
mipmap-b+fr+FR/ # franceza
fisier_imagine.jpg/png/bmp

Fișierele imagine trebuie să aibă aceleași caractersitici (dimensiune,


codare, etc.).

48
Pentru a adapta aplicația la diferite tipuri de ecrane, trebuie incluse în
proiect resurse potrivite diferitelor caracteristici.
În directorul res avem următoarele subdirectoare care pot fi setate
pentru caracteristicile ecranelor:
 res/drawable/ - fișiere imagine (.png, .9.png, .jpg, .gif) sau Xml
care pot fi compilate în fișiere imagine. Necesită foldere
denumite cu <density-qualifiers> pentru diferite caracteristici
ecran (hdpi, mdpi, ldpi, xhdpi, etc.)
 res/mipmap – fișiere imagine, cum ar fi iconițele pentru Action
Bar. Necesită foldere denumite cu <density-qualifiers> pentru
diferite caracteristici ecran (hdpi, mdpi, ldpi, xhdpi, etc.)
 res/layout/ - fișiere Xml pentru organizarea componentelor
grafice

49
 res/anim/ - fișiere animație, necesită foldere denumite cu
<qualifiers> pentru diferite caracteristici ecran
 res/xml/ - fișiere xml, necesită foldere denumite cu <qualifiers>
pentru diferite caracteristici ecran
 res/raw/
Imaginile incluse într-un proiect Android pot fi:
 create cu alte aplicații
 generate folosind aplicația Image Asset Studio pusă la dispoziție
de Android Studio
https://developer.android.com/studio/write/image-asset-studio.html

50
Imaginile, pentru a putea fi scalate, trebuiesc generate în format
vectorial astfel:
 xhdpi: 2.0
 hdpi: 1.5
 mdpi: 1.0 (baseline)
 ldpi: 0.75
Exemplu: pentru o imagine de 100x100 pixels pentru dispozitive cu
densitate mdpi, trebuiesc generate următoarele resurse: 200x200 –
xhdpi, 150x150 – hdpi, 75x75 – ldpi.

51
Pentru a crea o iconiță a aplicației în modul de vizualizare Android, se
selectează
res->New->Image Asset sau res->New->Vector Asset

52
Se pot genera astfel iconițe pentru aplicație (launcher icons) ce vor fi
salvate în directorul res/mipmap, iconițe pentru MenuBar sau diverse
alte imagini ce vor fi salvate în directorul res/drawable. Iconițele pot fi
create pe baza unor șabloane ClipArt sau a unor imagini alese de
utilizator în format (svg sau psd).
Pentru crearea imaginilor vectoriale se pot folosi aplicații dedicate
(ex. Online https://vectr.com).
De exemplu, atunci când se creează o iconița pentru aplicație, în
resurse vor fi introduse următoarele fișiere:
res/
mipmap-mdpi/ic_launcher.png (48x48 pixels)
mipmap-hdpi/ic_launcher.png (72x72)
mipmap-xhdpi/ic_launcher.png (96x96)
mipmap-xxhdpi/ic_launcher.png (144x144)
mipmap-xxxhdpi/ic_launcher.png (192x192)

53
Layout - Xml
 Atribute folosite în fişierul layout /layout/main.xml:

xmlns:android Declararea spaţiului de nume pentru


atributele Android. Toate elementele
rădăcină dintr-un layout trebuie să aibă
definit acest atribut
android:id Identificator unic pentru fiecare
componentă grafică. Acest ID poate fi
folosit pentru a referi componenta grafică
din codul sursă sau din alte fişiere xml.
android:layout_ Lăţimea layout-ului. Când valoarea este
width "fill_parent" arată că acea componentă
poate lua lăţimea întregului ecran.

54
android:layout_ Înălţimea layout-ului.
height
android:text Setează textul de afişat în TextView. În
loc de valoare se poate folosi o referire la
o resursă de tip „string” definită în
fişierul /values/strings.xml. Folosirea
resurselor string ajută la
internaţionalizare.

55
Layout – manager de poziţionare

1. ConstraintLayout
2. RelativeLayout
3. FrameLayout
4. LinearLayout
5. TableLayout
6. GridLayout

56
1. ConstraintLayout
Manager de poziționare dinamic care asigură poziționarea și
dimensiunea componentelor în mod flexibil.

Se pot seta următoarele constrângeri:


 Poziție relativă – orizontal (left, right, start/end side), vertical (top,
bottom, text baseline) – constrânge marginea unei componente la
oricare din marginile altei componente

57
 Margini

 Aliniere centru
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"

 Aliniere cu valori bias


 Poziționare circulară

58
 Vizibilitate
 Dimensiuni
 Înlănțuire

59
Exemplu – Android Studio -LayoutConstraint

60
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/darker_gray"

tools:context="devicesscreens.com.example.layoutconstraint.Ma
inActivity">

<TextView
android:id="@+id/textView1"
android:layout_width="123dp"
android:layout_height="32dp"
android:background="@android:color/holo_blue_bright"
android:text="@string/prima_eticheta"
android:textColor="@color/colorPrimaryDark"
android:textSize="18sp"

app:layout_constraintBottom_toBottomOf="@android:id/home"
app:layout_constraintLeft_toLeftOf="parent"
61
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_bias="0.05"
tools:layout_editor_absoluteX="16dp" />

<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_orange_light"
android:text="@string/a_doua_eticheta"
android:textColor="@android:color/holo_green_dark"
android:textSize="24sp"
app:layout_constraintLeft_toRightOf="@+id/textView1"
app:layout_constraintTop_toBottomOf="@+id/textView1" />

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/holo_orange_dark"
android:text="@string/a_treia_eticheta"
android:textColor="@android:color/holo_red_dark"
62
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="@+id/textView2"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintVertical_bias="0.5" />
</android.support.constraint.ConstraintLayout>

63
2. RelativeLayout – se specifică poziţia relativă a unui obiect faţă de
celelalte obiecte (left) sau faţă de părinte (top). Toolbar-ul Layouts.
o android:layout_above
o android:layout_alignBaseline
o android:layout_alignBottom
o android:layout_alignLeft
o android:layout_alignRight
o android:layout_alignTop
o android:layout_below
o android:layout_centerHorizontal If true, centers this child
horizontally within its parent.
o android:layout_centerInParent If true, centers this child
horizontally and vertically within its parent.
o android:layout_centerVertical If true, centers this child
vertically within its parent.
o android:layout_toLeftOf
o android:layout_toRightOf
64
Exemplu – Android Studio -LayoutRelative
Fișierul activity_main.xml (parțial):
<RelativeLayout
android:layout_width="315dp"
android:layout_height="382dp"
android:layout_margin="20dp"
android:background="@android:color/darker_gray"
tools:layout_editor_absoluteX="33dp"
tools:layout_editor_absoluteY="72dp"
app:layout_constraintBottom_toTopOf="parent"
app:layout_constraintTop_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="parent"
app:layout_constraintRight_toLeftOf="parent">

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="46dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
65
android:layout_marginStart="15dp"
android:layout_marginTop="43dp"
android:background="@android:color/holo_blue_bright"
android:text="@string/eticheta1"
android:textColor="@color/colorPrimary"
android:textSize="18sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_bias="0.172"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.121" />

66
67
3. FrameLayout
FrameLayout în Android Studio formează o grilă cu celule aliniate pe
rânduri și coloane. În fiecare celulă se pot adăuga componente grafice.
Este util atunci când include doar o componentă (de exemplu o listă).
Dacă sunt mai multe componente acestea se vor suprapune.

Exemplu – Android Studio -LayoutFrame


Fișierul activity_main.xml (parțial):

<FrameLayout
android:layout_width="368dp"
android:layout_height="231dp"
android:background="@android:color/darker_gray"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="16dp">

<TextView
android:id="@+id/textView1"

68
69
4. LinearLayout – aliniază toate componentele pe o singură direcţie –
vertical sau horizontal – respectând marginile dintre obiecte, alinierea
acestora (gravity: left, center, right, top, bottom, center_vertical,
fill_vertical, center_horizontal, fill_horizontal, fill) şi importanţa
(weight – permite să ocupe spaţiul liber rămas la părinte, proporţional
cu importanţa sa; implicit este 0). Introduce scroll dacă este nevoie.
Opţiunea se găseşte în toolbar-ul Layouts. Componentele pot fi
aranjate pe linii (vertical) sau pe coloane (orizontal). Componentele
nu sunt obligatoriu aliniate.

70
Exemplu –Android Studio-LayoutLinear

71
Fișierul activity_main.xml (parțial):

<LinearLayout
android:layout_width="368dp"
android:layout_height="231dp"
android:background="@android:color/darker_gray"
android:orientation="vertical"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">

<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"

72
5. TableLayout – poziţionează componentele într-un tabel (cu un
număr arbitrar de rânduri şi coloane) pe rânduri şi coloane, fără liniere
(nu se văd borduri la celule). În fiecare celulă a tabelului se poate
introduce o componentă grafică. Componentele grafice sunt introduse
pe rânduri de la stânga la dreapta. Rândurile se redimensionează
automat pentru a cuprinde cea mai lată coloană. Opţiunea se găseşte în
toolbar-ul Layouts.

73
6. GridLayout
O grilă care se adaugă la alt manager și este organizată pe rânduri care
separă zona vizualizată în celule. Permite aranjarea pe mai multe
rânduri şi coloane de dimensiune variabilă, pe poziţii diferite în
fiecare celulă.

Exemplu-AndroidStudio-LayoutGrid

Fișierul activity_main.xml (parțial)


<GridLayout
android:layout_width="368dp"
android:layout_height="88dp"
android:background="@android:color/darker_gray"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="64dp">

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
74
android:layout_height="wrap_content"
android:layout_column="1"
android:layout_row="1"
android:background="@android:color/holo_blue_bright"
android:text="Prima eticheta"
android:textColor="@color/colorPrimary"
android:textSize="18sp" />

75
Componente grafice pentru ieșiri
 Eticheta – toolbar TextView

 Toast - afișează un mesaj într-un popup disponibil pentru o


perioadă scurtă de timp deasupra ferestrei principale care rămâne
vizibilă și interactivă. Clasa android.widget.Toast

76
Componente grafice de control
 Buton cu o stare stabilă – Button – toolbar Widgets

 Buton cu două stări stabile – ToggleButton – toolbar Widgets

 Casetă de validare – CheckBox – toolbar Widgets

 Buton radio – RadioButton – toolbar Widgets

 Casetă de validare cu text – CheckedTextView – toolbar Widgets

 Bară de căutare – SeekBar –toolbar Widgets

 Listă ascunsă – Spinner – toolbar Widgets

77
 Zone de text – toolbar Text. Sunt de mai multe tipuri: zonă de text
editabilă pe un rând (PlainText) sau pe mai multe rânduri
(Multiline Text), parola (Password), adresă (Postal Address), dată
(Date), timp (Time), email (E-mail), telefon (Phone), numeric
(Number), autocompletare (AutoComplete).

78
 TimePicker, DatePicker – selectare timp, dată– toolbar Date

79
Evenimente
 Sunt generate de subclasele clasei View.
 Metodele care tratează evenimente (ascultătoare de evenimente)
trebuie suprascrise în aplicație.
 Cele mai comune metode sunt:
o onClick() – este atinsă componenta grafică sau se dă click pe
aceasta.
o onLongClick() – se apasă mai mult pe componenta grafică
o onFocusChange() – se intră/iese deasupra componente grafice
o onKey() – se apasă o tastă a dispozitivului
o onTouch() – se apasă, se eliberează, se mișcă cursorul
o onCreateContextMenu() – se creează meniul contextual

80
Exemplu-AndroidStudio-ComponenteGrafice

81
Fișierul activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"

tools:context="devicesscreens.com.example.componentegrafice.M
ainActivity">

<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:textColorHint="@color/colorAccent"
android:hint="@string/editText1Hint"
app:layout_constraintLeft_toLeftOf="parent"
82
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"/>

<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:ems="10"
android:inputType="date"
android:hint="@string/editText2"
android:textColorHint="@color/colorAccent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/editText1"
android:layout_marginStart="16dp"
android:layout_marginVertical="10dp"/>

<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
83
android:text="@string/afiseaza"
app:layout_constraintStart_toEndOf="@id/editText2"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
android:layout_marginTop="75dp" />

<TextView
android:id="@+id/textView1"
android:layout_width="340dp"
android:layout_height="50dp"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
android:text="@string/textView1"
android:textSize="18sp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@id/editText2"
/>

<CheckBox
android:id="@+id/checkBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
84
android:text="@string/checkbox"
android:checked="false"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/textView1"
android:layout_marginStart="16dp"
android:layout_marginTop="30dp" />

<TextView
android:id="@+id/textView2"
android:layout_width="104dp"
android:layout_height="30dp"
android:text="@string/textView2"
app:layout_constraintStart_toEndOf="@id/checkBox"
app:layout_constraintTop_toBottomOf="@id/textView1"
android:layout_marginStart="60dp"
android:layout_marginTop="40dp" />

<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/checkBox" >
85
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="15dp"
android:layout_weight="1"
android:onClick="onRadioButtonClicked"
android:checked="true"
android:text="@string/radiobutton1"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="parent" />

<RadioButton
android:id="@+id/radioButton2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_weight="1"
android:onClick="onRadioButtonClicked"
android:text="@string/radiobutton2"
86
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="parent" />
</RadioGroup>

<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textview3"
app:layout_constraintStart_toStartOf="@id/textView2"
app:layout_constraintTop_toBottomOf="@id/textView2"
android:layout_marginStart="1dp"
android:layout_marginTop="30dp" />

<Spinner
android:id="@+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/checkBox"
android:layout_marginStart="16dp"
android:layout_marginTop="90dp" />
87
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/textview"
app:layout_constraintStart_toStartOf="@id/textView3"
app:layout_constraintTop_toBottomOf="@id/textView3"
android:layout_marginStart="1dp"
android:layout_marginTop="30dp" />

<ListView
android:id="@+id/listView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="10dp"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/spinner" />

</android.support.constraint.ConstraintLayout>

88
Fișierul layout/activity_listview.xml
Permite definirea ascultătorului pentru listă.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout

xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:id="@+id/textViewList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="2dp"
android:textColor="@color/colorAccent" />

</android.support.constraint.ConstraintLayout>

89
Fișierul Java:

package devicesscreens.com.example.componentegrafice;

import …

public class MainActivity extends AppCompatActivity


implements AdapterView.OnItemSelectedListener {
TextView textView1,textView2, textView3, textView4;
Spinner spinner;
Button button;
EditText editText1,editText2;
CheckBox checkBox;
RadioButton radioButton1, radioButton2;
ListView list;
String[] spinnerItems={"Spinner-1","Spinner-2","Spinner-
3","Spinner-4"};
String[] listItems={"List-1","List-2","List-3","List-4"};

@Override
90
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)this.findViewById(R.id.button1);
editText1 =
(EditText)this.findViewById(R.id.editText1);
editText2 =
(EditText)this.findViewById(R.id.editText2);
textView1 =
(TextView)this.findViewById(R.id.textView1);
checkBox =
(CheckBox)this.findViewById(R.id.checkBox);
textView2 =
(TextView)this.findViewById(R.id.textView2);
textView3 =
(TextView)this.findViewById(R.id.textView3);
textView4 =
(TextView)this.findViewById(R.id.textView4);

String dataCurenta = new SimpleDateFormat("dd-MM-


yyyy").format(Calendar.getInstance().getTime());
editText2.setText(dataCurenta);
91
button.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
textView1.setText(editText1.getText()+" -
"+editText2.getText());
}
});

checkBox.setOnClickListener(new
View.OnClickListener() {
public void onClick(View v) {
if(checkBox.isChecked())
textView2.setText("Bifat");
else textView2.setText("Ne-Bifat");
}
});

Spinner spinner = (Spinner)


this.findViewById(R.id.spinner);
ArrayAdapter adapter = new
ArrayAdapter(this,android.R.layout.simple_spinner_item,spinne
92
rItems);

adapter.setDropDownViewResource(android.R.layout.simple_spinn
er_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(this);

list = (ListView)findViewById(R.id.listView1);
ArrayAdapter<String> arrayAdapter = new
ArrayAdapter<String>(this, R.layout.activity_listview,
R.id.textViewList, listItems);
list.setAdapter(arrayAdapter);
list.setOnItemClickListener(new
AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
Toast.makeText(getApplicationContext(),"Lista
pozitia :"+position+" item: " +(String)
list.getItemAtPosition(position) , Toast.LENGTH_LONG)
.show();
}
93
});

}
//spinner
public void onItemSelected(AdapterView<?> parent, View
view, int position, long id) {
textView4.setText("Selectie spinner:
"+spinnerItems[position]);
}
//spinner
public void onNothingSelected(AdapterView parent) {
// Do nothing.
}
//spinner
public void setOnClickListener(AdapterView<?> parent,
View view, int position, long id) {
//textView4.setText("Selectie spinner:
"+spinnerItems[position]);
Toast.makeText(getApplicationContext(),
spinnerItems[position], Toast.LENGTH_LONG).show();
}
//radioButton group
94
public void onRadioButtonClicked(View view) {
boolean checked = ((RadioButton) view).isChecked();
switch(view.getId()) {
case R.id.radioButton1:
if (checked)
textView3.setText("Buton radio-1");
break;
case R.id.radioButton2:
if (checked)
textView3.setText("Buton radio-2");
break;
}
}
}

95
Internaționalizare
Android asigură suport pentru diferite limbi și culturi (format de
dată, timp, numere, monedă) prin intermediul setărilor legate de
localizare.
Diferitele variante pentru diferite limbi sunt memorate în
directoare separate în directorul /resources, respectând modelul:
<resource type>-b+<language code>[+<country code>]

Fișierul string.xml are câte o variantă în fiecare director


corespunzător unei limbi. Se păstrează denumirile variabilelor
folosite în setarea caracteristicilor componentelor grafice.

96
Apelul componentelor grafice în fișierele Java se face ca și cum ar
fi o singură variantă de limbă.

O listă cu setările pentru limbă:


http://stackoverflow.com/questions/7973023/what-is-the-list-of-
supported-languages-locales-on-android

Pentru a schimba setările de limbă, trebuie schimbate setările din


aplicația Settings a dispozitivului mobil.

97
Bara meniu - Exemplul - MenuBarExample
Convertirea unei imagini vectoriale (.svg) într-un fișier .xml:
 În folderul res se dă click dreapta ->new->create vector
asset
 Se alege fișierul .svg referință
 Se salvează fișierul xml rezultat în /drawable
https://developer.android.com/guide/topics/graphics/vector-
drawable-resources

98
99
Crearea unei pagini/fereastră cu bară de meniu de navigare:
File->New->Navigation Drawer Activity
Se creează o structură de managere de poziționare astfel:
 activity_main - fereastra principală care include o bară de meniu
(app_bar_main) și NavigationView
o content_main - conținutul paginii principale (în aplicația
MenuBarExample are o zonă de text, un buton și o etichetă)
o nav_header_main - partea de sus a meniului, cu iconită de start,
titlu și subtitlu
În fișierul MainActivity.java metoda pentru tratarea evenimentului
intrările din meniu:
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();

if (id == R.id.fereastra1) {
Toast.makeText(getApplicationContext(),"Click Item
menu" , Toast.LENGTH_LONG).show();
100
} else if (id == R.id.fereastra2) {
Intent intent = new Intent(this,
Main2Activity.class);
valoareDeTransmis = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, valoareDeTransmis);
startActivity(intent);

DrawerLayout drawer = (DrawerLayout)


findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}

101
Clasa Intent asigură legătura dintre două componente ale unei
aplicații (de exemplu două activități) și reprezintă intenția aplicației
de a face ceva. Parametrii constructorului clasei Intent sunt
componenta curentă (Context) și componenta viitoare în care
aplicația va furniza Intent-ul. Metoda putExtra transmite perechi
cheie-valoare (EXTRA_MESSAGE mesaj definit ca dată membră
finală a clasei și message). Cheia are ca prefix numele pachetului
pentru a asigura unicitatea în cazul în care se interacționează cu alte
aplicații.
Metoda startActivity() pornește o instanță specificată ca Intent.

102
Fișierul app/manifests/AndroidManifest.xml trebuie specificat că
are 2 ferestre și că prima fereastră este părintele celei de-a doua
(pentru a putea face corect comanda Back):
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.adina.menubarexample">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action
103
android:name="android.intent.action.MAIN" />

<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Main2Activity"
android:label="@string/item_fereastra2"
android:parentActivityName=".MainActivity" >
<meta-data

android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>

</application>

</manifest>

Fișierul Main2Activity.java, definește un ActionBar și un Intent


prin care face legătura cu prima fereastră.
104
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
actionBar=getSupportActionBar();
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayUseLogoEnabled(true);

// obtine Intent care a deschis aceasta activitate si


obtine sirul de afisat
Intent intent = getIntent();
String message =
intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

// Capture the layout's TextView and set the string as


its text
TextView textView = (TextView)
findViewById(R.id.textView2);
textView.setText("Buna "+message);

105
106
Style
 proprietăți care definesc modul de vizualizare al unei componente
grafice.
 Sunt definite în res/values/styles.xml
 Se poate specifica înălțimea, bordura, caracteristicile fontului,
culorile de background sau foreground, etc.
 Este predefinit când se creează un nou proiect, dar pot fi definite de
programator.

Theme
 Tema aleasă pentru întreaga aplicație
 Se definește atunci când se creează un nou proiect sau se setează în
fișierul AndroidManifest.xml

107
În Android este posibilă utilizarea culorilor transparente. Pentru acest
lucru se pot utiliza următoarele valori ce se vor adăuga după # și
înaintea codului inițial al culorii:
 100% — FF  65% — A6  30% — 4D
 95% — F2  60% — 99  25% — 40
 90% — E6  55% — 8C  20% — 33
 85% — D9  50% — 80  15% — 26
 80% — CC  45% — 73  10% — 1A
 75% — BF  40% — 66  5% — 0D
 70% — B3  35% — 59  0% — 00

108
Exemplu de folosire a style/theme

1. 2.

109
Îîn fișierul AndroidManifest.xml se modifică AppTheme cu
CustomThemeBlue/CustomThemeMagenta
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/CustomThemeBlue" >
<!--android:theme="@style/AppTheme" > -->

De exemplul, în fig.1 se modifică în fișierul res/values/styles.xml


<color name="magenta">#b0b0ff</color>
<style name="CustomThemeBlue"
parent="android:Theme.Light">
<item
name="android:windowBackground">@color/magenta</item>
<item
name="android:colorBackground">@color/magenta</item>
110
</style>
<style name="AppBaseTheme"
parent="android:Theme.Light">

De exemplul, în fig.2 se modifică în fișierul res/values/styles.xml


<color name="blue">#ff0000ff</color>
<style name="CustomThemeBlue"
parent="android:Theme.Holo.Light">
<item
name="android:windowBackground">@color/blue</item>
<item
name="android:colorBackground">@color/blue</item>
</style>
<style name="AppBaseTheme"
parent="android:Theme.Holo.Light">

111
Android Icon
http://developer.android.com/guide/practices/ui_guidelines/icon_desig
n.html

112
 TabHost - aranjează mai multe ecrane în mai multe tab-uri
 Google Map View
 Web View

http://developer.android.com/resources/tutorials/views/index.html

113

S-ar putea să vă placă și