Proiectarea Unei Aplicatii Android Convertor Unitati de Masura

Cuprins

Introducere:

Descrierea aplicației

Scopul aplicației

Cerințele problemei și specificațiile funcționale

2.2.1 Cerințele temei

2.2.2 Lista figurilor

2.2.3 Lista tabelelor

Proiectarea sistemului

Sistemul de operare Android

Mediul de dezvoltare

Configurare mediu de lucru

Limbajul de programare JAVA pentru Android

Activitate

Layout

Fragment

Navigation Drawer

Libraria SQLite

Resurse

Implementarea soluției

Cercetare în domeniul temei

Creare proiect

Implementare cod și realizarea interfeței

Metode și algoritmi

Metode de calcul a valorilor

Metoda de înlocuire a fragmentelor

Metoda de salvare a conversiei

Metoda de încărcare a datelor în ListView

Baza de date a aplicației

Afișarea datelor în format matematic

Manual de utilizare

Concluzii

Bibliografie

Anexe

Codul aplicației

Introducere

Descrierea aplicației

Aplicația Convertor reunește cele mai importante funcționalități necesare unei persoane care lucreaza cu unități inginerești, convertind o valoare în diferite unități de masură din aceeași categorie.

Motivația

Motivația principală pentru dezvoltarea acestei aplicații a fost crearea unei aplicații ușor de utilizat,cu cele mai frecvent utilizate mărimi, care să folosească sistemul oficial de măsurare în aproape fiecare țară din lume.

CerinȚele problemei Și specificaȚiile funcȚionale

Cerințele temei

Lista figurilor

Figura 1 – Arhitectura Android

Figura 2 – Deschide „Variabile de sistem”

Figura 3 – Variabila noua de sistem

Figura 4 – Datele variabilei de sistem JDK

Figura 5 – Componente Android SDK

Figura 6 – Instalare ADT

Figura 7 – Selectare “Developer Tools”

Figura 8 – Selectare director SDK

Figura 9 – Structura layout-ului android

Figura 10 – Ciclul de viata al unui fragment

Figura 11 – Pasul 1 Creare Proiect

Figura 12 – Pasul 2 Creare Proiect

Figura 13 – Pasul 3 Creare Proiect

Figura 14 – Pasul 4 Creare Proiect

Figura 15 – Pasul 5 Creare Proiect

Figura 16 – Instrucțiuni de utilizare 1

Figura 17 – Instrucțiuni de utilizare 2

Figura 18 – Instrucțiuni de utilizare 3

Proiectarea sistemului

Sistemul de operare Android

Android este un sistem de operare pentru telefoanele mobile bazat pe nucleul Linux. Compania Google a dezvoltat această platformă software cu perspectiva de a asigura un sistem flexibil și upgradabil care din octombrie 2008 este disponibil ca Free-Software si Open Source. Android permite dezvoltatorilor să scrie cod gestionat în limbajul Java, controlând dispozitivul prin intermediul bibliotecilor Java dezvoltate de Google.

Motorul Android este reprezentat în primul rând de un set de biblioteci care permit utilizatorilor să dezvolte aplicații Android folosind limbajul de programare Java. Aceste biblioteci oferă acces la diferite funcții ale telefonului mobil: Video/Audio,Conectivitate,Mesagerie,Apel, Locație,etc.

Cu ajutorul Android se pot dezvolta:

Aplicații care pot accesa Bluetooth,3G,WiFi,Camera,GPS,accelerometru

Aplicații pentru stocarea datelor cu ajutorul librăriei SQLite

Aplicații care includ suport media pentru redarea imaginilor sau videoclipurilor în diferite formate: AMR , MP3, MPEG4, H.264, AAC, PNG, JPG, GIF

Aplicații Android Beam – o tehnologie bazată pe NFC careprin apropierea dispozitivelor mobile permite utilizatorilor să partajeze conținut instant

Aplicații multi-touch : suportă ecrane cu posibilitate de contact în mai multe puncte concomitant.

Arhitectura sistemului Android se poate observa în Figura 1.

Fig. 1 – Arhitectura Android

Mediul de dezvoltare

Un mediu de dezvoltare  este un set de programe care ajută programatorul în scrierea programelor. Un mediu de dezvoltare combină toți pașii necesari creării unui program : editarea codului sursă, compilarea, depanarea,testarea, generarea de documentație într-un singur soft, care, de regulă, oferă o interfață cu utilizatorul grafică.

  Eclipse este un IDE apreciat de mulți dezvoltatori și este, asemeni Android, un open-source care oferă o integrare foarte bună cu platforma, sub formă de perspective dedicate.

Kitul de dezvoltare software Android(Android SDK) este un kit care permite dezvoltarea aplicațiilor Android și care include codul sursă al unor proiecte simple, un emulator și biblioteci necesare.

Pentru a putea dezvolta aplicații Android, folosind Eclipse și Android SDK, este necesară instalarea plugin-ului ADT(Android Development Tools) – un plugin care extinde posibilitățile Eclipse pentru a realiza mai rapid aplicații, pentru adăugarea de pachete ce folosesc Android Framework API, dar și pentru exportarea aplicațiilor sub format .apk pentru distribuirea lor.

Configurare mediu de lucru

Pentru configurarea mediului de lucru s-au efectuat următorii pași :

Descărcarea și instalarea JDK(Java Development Kit);

Descărcarea și instalarea Eclipse IDE;

Crearea unei variabile de system Java : My Computer -> “Properties” -> “Advanced System Settings” , iar de aici se urmează pașii din imagini:

Se face click pe “Environment Variables”

Fig. 2 – Deschide “Variabile de sistem”

Se apasă butonul “New”

Fig. 3 – Variabila noua de sistem

Se introduce numele “JDK_HOME” și locația în care este instalat kitul JDK, în cazul de față “C:\Program Files\Java\jdk1.8.0_25\”

Fig.4 – Datele variabilei de sistem JDK

Descărcarea și instalarea Android SDK;

Utilizând Android SDK Manager s-au descărcat componentele care includ instrumente de dezvoltare, documentația, platforme Android, librării externe, driver-ul USB pentru Windows și exemple de aplicații:

Fig.5 – Componente Android SDK

Instalare ADT(Android Development Toolkit) Pluginpentru Eclipse:

Click “ Help” -> “Instal new software” din meniul aplicației Eclipse

Click “Add”

În formularul “Add Repository” se introduce numele ADT Plugin și pentru “Location” se completează cu adresa următoare:https://dl-ssl.google.com/android/eclipse/

Fig.6 – Instalare ADT

În fereastra de dialog Available Softwarese selectează checkbox-ul de lângă Developer Tools

Fig.7 – Selectare “Developer Tools”

Click “Next” și apoi “Finish”

Repornire Eclipse;

Configurare plugin-ul ADT pentru Eclipse:

Se deschide meniul Preferences prin selectarea “Window” -> “Preferences”

Selectarea categoriei “Android” din meniul din stânga

Click “Browse” și selectarea directorului unde a fost instalat Android SDK

Click Apply

Fig.8 – Selectare director SDK

Limbajul de programare JAVA pentru Android

Activitate

În Android, o activitate reprezintă o fereastră care conține interfața grafică a aplicației. O aplicație poate conține 0 sau mai multe activități (tipic, există măcar o activitate), scopul acestora fiind acela de a interacționa cu utilizatorul. De obicei, o activitate implică un nivel de procesare redus, astfel încât să se asigure operarea aplicației în timp real.

O activitate este reprezentată prin intermediul unei clase care extinde Activity. Toate activitățile din cadrul unei aplicații Android trebuie să fie declarate în fișierul AndroidManifest.xml.

<activity

            android:name="ActivityName"

            android:label="ActivityName">

    </activity>

Fiecare activitate are propriul său ciclu de viață, independent de ciclul de viață al procesului asociat aplicației. O activitate are un ciclu de viață complex, deoarece aplicațiile pot avea activități multiple și doar una este în prim-plan; utilizând managerul de activități, sistemul Android gestionează o stivă de activități care se găsesc în diferite stări (pornire, în execuție, întreruptă, oprită, distrusă);

Activitatea este una dintre cele mai importante componente (alături de servicii și broadcast receivers) ale unei aplicații Android, deoarece este strâns legată de interfața cu utilizatorul. O activitate este utilizată pentru a gestiona interfața cu utilizatorul și este echivalentă cu fereastra sau formularul din aplicațiile desktop.

Înțelegerea modului în care se controlează activitatea permite să:

utilizați ciclul de viață al activității pentru a crea, vizualiza, utiliza și a opri activitățile;

salvați datele utilizatorului înainte ca activitatea să fie oprită și le restaurați atunci când activitatea este readusă în prim-plan;

creați aplicații cu mai multe formulare sau activități;

Ciclul de viață al unei activități descrie starea în care o activitate poate fi la un moment dat.

onCreate(Bundle) – apelată când activitatea este creată; folosind argumentul metodei de tip Bundleexistă posibilitatea să restabiliți starea activității, care a fost salvată într-o sesiune anterioară; după ce activitatea a fost creată, va fi pornită (onStart());

onStart() – apelată în cazul în care activitatea urmează să fie afișată; din acest punct, activitatea poate veni în prim-plan (onResume()) sau rămâne ascunsă în fundal (onStop());

onRestoreInstanceState(Bundle) – apelată în cazul în care activitatea este inițializată cu datele dintr-o stare anterioară, ce a fost salvată; în mod implicit, sistemul restaurează starea interfeței cu utilizatorul (starea controalelor vizuale, poziția cursorului, etc);

onResume() – apelată când activitatea este vizibilă, iar utilizatorul poate interacționa cu aceasta; din această stare, activitatea poate fi plasată în fundal, devenind întreruptă (onPause());

onRestart() – apelată în cazul în care activitatea revine în prim-plan dintr-o stare oprită (stopped); după aceasta, activitatea este pornită (onStart()) din nou;

onPause() – apelată atunci când sistemul aduce în prim-plan o altă activitate; activitatea curentă este mutată în fundal și mai târziu poate fi oprită (onStop()) sau repornită și afișată (onResume()); acesta este un moment bun pentru a salva datele aplicației într-un mediu de stocare persistent (fișiere, baze de date), deoarece după această fază activitatea poate fi terminată și distrusă fără a se anunța acest lucru.

onSaveInstanceState(Bundle) – apelată pentru a salva starea curentă a activității; în mod implicit, sistemul salvează starea interfeței cu utilizatorul;

onStop() – apelată în cazul în care activitatea nu mai este utilizată și nu mai este vizibilă, deoarece o altă activitate interacționează cu utilizatorul; din acest punct, activitatea poate fi repornită (onRestart()) sau distrusă (onDestroy());

onDestroy() – apelată în cazul în care activitatea este distrusă, iar memoria sa eliberată; acest lucru se poate întâmpla în cazul în care sistemul necesită mai multă memorie sau dacă programatorul termină explicit activitatea apelând metoda finish() din clasa Activity;

Layout

Un layout este de fapt un document xml reprezentând o structură vizuală sau o interfață grafică care are rolul de a descrie cum sunt așezate componentele în interiorul acesteia. Componentele interfeței grafice pot fi declarate direct în fișierul XML sau adăugate programabil. Prima metoda are avantajul de separare al interfeței grafice de cod, ceea ce oferă și posibilitatea de a modifica mai ușor și mai rapid interfața graficăsau de a crea mai multe interfețe grafice pentru diferite rezoluții, orientări sau limbă.

Structura fișierului XML este asemănătoare unui document HTML, fiecare fișier trebuie să conțină doar un element rădăcină care trebuie să fie un View sau un obiect ViewGroup, iar componentele care fac parte din structura layout-ului au proprietăți care se declară sub formă de elemente imbricate.

Tipuri de layout-uri:

LinearLayout – Este unul dintre layout-urile fundamentale în Android. După cum indică și numele, are un aspect linear și așează copiii săi întru-un grup care are o singură direcție,vertical sau orizontal.

RelativeLayout – Folosind acest layout copiii pot fi așezați cu referire la frați(la stânga,la dreapta,sub sau deasupra) sau la părinte(centrat orizontal,centrat vertical,ambele sau aliniat la oricare dintre margini).

GridLayout – Grid Layout este un aspect Android care plasează copiii săi într-o grilă dreptunghiulară. GridLayout folosește o rețea de linii de infinit-subțiri pentru a separa zona sa de desen in: rânduri, coloane și celule.

ListView – ListView este un grup de vedere care afișează o listă de elemente derulant. Elementele din listă sunt inserate automat în lista folosind un adaptor,încarcă conținutul de la o sursă, cum ar fi o interogare în baza de date sau valori hardcodate.

Fiecare clasă ViewGroup implementează o clasă imbricata care extinde ViewGroup.LayoutParams. Această clasă conține tipurile de proprietate care definesc dimensiunea și poziția pentru fiecare copil. ViewGroup-ul mamă definește parametrii de aspect pentru fiecare View copil.

Fig.9 – Structura layout-ului android

Controalele de intrare sunt componentele interactive în interfața cu utilizatorul. Android oferă o mare varietate de controale care le puteți utiliza în UI, cum ar fi butoane, câmpuri text, checkbox, butoane de zoom, butoane de comutare și multe altele.

Controale în crearea layout-urilor aplicației:

Buton : control poate fi apăsat pentru a executa o acțiune specificată și i se pot atribui evenimente.

TextView : afișează text pentru utilizator și, opțional, permite editarea. Un TextView este un editor de text complet, cu toate acestea, clasa de bază este configurata să nu permită editarea;

EditText: un camp text care poate fi editat,utilizatorul poate introduce manual caractere când interacționează cu aplicația. Acest control poate fi de mai multe tipuri,de exemplu AutoComplete,Numeric,Phone,Email,etc.

Spinner :oferă o modalitate rapidă de a selecta o valoare dintr-un set. În starea implicită arată valoarea selectată în mod curent. Atingerea acestuia afișează un meniu vertical cu toate celelalte valori disponibile, din care utilizatorul poate selecta unul nou. Valorile pot fi încărcate dintr-un string array sau dintr-o listă.

Fragment

Un fragment este o sub-activitate, o porțiune de interfață cu utilizatorul într-o activitate. Într-o activitate se pot combina mai multe fragmente, dar de asemenea poate să existe doar unul singur. Un fragment ca o secțiune de activitate, care are propriul său ciclu de viață, primește propriile evenimente de intrare, care se pot adăuga sau elimina în timp ce activitatea se execută.

Avantajele și proprietățile fragmentelor:

Un fragment are propriul aspect și propriul comportament cu propriile sale cicluri de viață.

Se pot adăuga sau elimina fragmente într-o activitate în timp ce activitatea se execută.

Se pot combina mai multe fragmente într-o singură activitate pentru a construi o interfață multi-plan.

Un fragment poate fi utilizat în mai multe activități.

Ciclul de viață fragment este strâns legat de ciclul de viață al activității sale gazdă, ceea ce înseamnă că atunci când activitatea este întreruptă, toate fragmentele disponibile în activitate vor fi, de asemenea, oprite.

Un fragment poate implementa un comportament care nu are nicio componentă care să interacționeze direct cu utilizatorul.

Un fragment se creează prin extinderea din clasa Fragment și poate fi introdus în aspectul activității prin declararea în fișierul de layout ca element de tip <fragment>.

Într-o mare măsură putem spune că fragmentele elimină limitarea de a avea o singură activitate pe ecran la un moment dat. Cu ajutorul acestora putem avea o singură activitate care cuprinde mai multe fragmente cu aspect propriu și ciclu de viață diferit.

Fragmentele Android au propriul lor ciclu de viață foarte asemănător cu o activitate Android.Această secțiune informează pe diferite etape ale ciclului său de viață.

Fig.10 – Ciclul de viata al unui fragment

Lista metodelor care pot fi suprascrise în clasa Fragment :

onAttach()- Instanța fragment este asociată unei instanțe de activitate.Fragmentul și activitatea nu sunt pe deplin inițializate.

onCreate()- Sistemul solicită această metodă la crearea fragmentului. Trebuiesc inițializate componente esențiale ale fragmentului care trebuie păstrate atunci când fragmentul este întrerupt sau oprit, apoi reluat.

onCreateView()- Sistemul solicită acest apel invers, atunci interfața grafică este pentru prima data creată.

onActivityCreated()–Aceasta metodă este chemată după metoda onCreateView() atunci când activitatea gazdă este creată.

onStart() – Metoda chemată când fragmentul devine vizibil.

onResume() – Metoda chemată când fragmentul devine vizibil.

onPause() – Sistemul cheamă această metodă atunci când utilizatorul părăsește fragmentul.

onStop() – Metoda chemată când fragmentul este oprit.

onDestroyView() – După ce este chemată această metodă fragmentul se va distruge.

onDestroy() –Metoda chemată pentru a face curățarea finală a fragmentului.

Pentru a putea schimba diferite fragmente în interiorul unui container dintr-o activitate se folosescmetodele „replace()” și „commit()” ale clasei FragmentTransaction și metoda „beginTrasaction().replace” din clasa FragmentManager.

Navigation Drawer

Navigation Drawer sau sertarul de navigare este un panou care afișează principalele opțiuni de navigare pe marginea din stânga a ecranului. Acesta este ascuns de cele mai multe ori, dar este afișat atunci când utilizatorul face swipe cu un deget de la marginea din stânga a ecranului sau când utilizatorul atinge pictograma aplicației în bara de acțiune care se află în stânga sus.

Sertarul de navigare trebuie să conțină o listă a cărei gravitate să fie setată orizontal. În activitate, unul dintre primele lucruri care trebuie făcut este inițializarea listei de articole. Lista este populată de un adaptor (cum ar fi ArrayAdapter sau SimpleCursorAdapter) care încarcă datele dintr-un vector de stringuri,fiecare string devenind un articol căruia i se pot atribui evenimente.

Librăria SQLite

SQLite este un sistem de management al bazelor de date relaționale conținute într-o bibliotecă de programare C. Spre deosebire de multe alte sisteme de management de baze de date, SQLite nu este un motor de baze de date client-server ci este un motor de baze de date SQL încorporat. Baza de date creată cu ajutorul librariei SQLite poate conține tabele,view-uri, trigere sau indici și este scrisă direct într-un fișier disc. Formatul fișierului bazei de date este cross-platform, adică există posibilitatea copierii bazei de date între sisteme pe 32 și pe 64 biți și pot fi liber partajate între mașini cu ordine diferită de octeți.

SQLiteOpenHelper este o clasă care ajută la crearea și actualizarea informațiilor din baza de date. Pentru a avea acces la aceste operațiuni trebuie creată o subclasă a clasei SQLiteOpenHelper în care se vor implementa metodele onCreate() și onUpgrade() în interiorul cărora se execută query-ul de creare al bazei de date și al tabelelor prin sintaxa execSQL(query-ul de creare)respectiv de update.

SQLiteDatabase este clasa ce permite manipularea datelor din baza de date prin metode ca insert(), delete(), update() . O altă metodă este execSQL() care permite execuția directă a unei instrucțiuni SQL.

Content Values este un obiect în care poți defini și seta chei și valori. Cheia obiectului Content Values reprezintă un identificator al unei coloane din table, iar valoarea este informația stocată în baza de date în acea coloană. Acest obiect se folosește atât pentru update-uri, cât și pentru inserări în baza de date. Pentru selectarea informațiilor se folosește un cursor.

Cursorul este un obiect care returnează o linie din rezultatul returnat de o interogare în baza de date. Obiectul de tip cursor poate apela următoarele funcții :

-moveToFirst(): mută cursorul pe prima linie;
– moveToNext(): mută cursorul pe următoarea linie;
– getCount(): returnează numărul total de linii întoarse de querry;
– isAfterLast(): verifică dacă s-a ajuns la sfârșitul interogării;
– get*(): funcție care ajută la accesarea datelor din coloanele returnate de interogare.

Interogările în baza de date se pot face prin intermediul metodelor rawQuerry() și querry() sau prin clasa SQLiteQueryBuider.

Cele mai mari avantaje care le oferă libraria SQLite :

Nu necesită un server care să fie inițializat, configurat sau instalat

Orice program care este capabil să acceseze discul poate să citească și să folosească o bază de date

Cod de bază mic: mai puțin de 250KiO configurat complet sau mai puțin de 150KiO cu caracteristici opționale omise

Codul este ușor de folosit, nivel de dificultate scăzut

Nu are dependențe externe

Șirurile și BLOB-urile sunt limitate doar de memoria disponibilă

Se poate seta să ruleze într-un spațiu de stivă de 4kb și 100kb memorie heap, ceea ce îl face perfect pentru device-urile cu capacitate de memorie restrânsă

Suportă baze de date de până la 2 terraocteți (2 ^ 41 octeți) în mărime

Resurse

Șirurile de text, bitmap-uri, fișiere video și audio reprezintă resurse ce sporesc experiența utilizatorului. În ciuda faptului că sunt controlate din codul sursă, acestea reprezintă resurse externe și recomandarea este să fie externalizate. Resursele sunt stocate în directorul “res” din cadrul proiectului Android. În scopul de a gestiona diferite tipuri de resurse, directorul res conține subfoldere specifice ca color, drawable, layout, animator, etc.

Pentru a facilita accesul și controlul resurselor din codul aplicației, compilatorul generează o clasă, numita R, care conține identificatori statici utilizați pentru referirea fiecărei resurse.

Resurse personalizate sunt utilizate pentru a crea efecte și animații customizate pentru anumite componente. Pentru a face acest lucru, pentru fiecare componentă este creat un fișier XML în res / director drawable în care este specificat ce imagine sau efect este utilizat pentru acțiuni diferite ale componentei, cum ar fi de apăsare pe un buton sau de focusare pe EditText.

Evenimente

Un eveniment este trimiterea unui mesaj. De exemplu un buton informează aplicația că utilizatorul l-a apăsat. Această informare se realizează cu ajutorul unui eveniment. Mesajele sosesc de la surse de evenimente, iar destinatarii acestor evenimente sunt recepționarii evenimentelor. La recepția evenimentului, în obiectul receptor se execută o metodă.

Destinatarul (obiectul receptor) trebuie să implementeze metode de tratare a tuturor tipurilor de evenimente al căror receptor poate fi. 
Exemple de tipuri de evenimente: 
ActionEvent  se generează la apăsarea butoanelor, selecția din meniuri, terminarea editării unei casete text (apăsarea tastei Enter în casetă). 
MouseEvent se generează la operarea cu mouseul pe suprafața componentei. Un eveniment de tip ActionEvent conține numele acțiunii, iar un eveniment de tip MouseEvent  descrie poziția mouse-ului, respectiv starea butoanelor.

Listener (Event Listener) se apelează atunci când utilizatorul interacționează cu interfața care provoacă un eveniment specific.

În Android, un listener de eveniment este o interfață în View care conține o singură metodă de apel invers. Aceste metode vor fi chemate atunci când userul declanșează evenimentul care este “ascultat”.

Handler(Event Handler) – atunci când un eveniment se întâmplă și este detectat de ascultătorul de eveniment, ascultătorul “cheamă” handler-ul care se “ocupă” de tratarea evenimentului.

Event Listeners and Event Handlers în Android.

Implementarea soluȚiei

Cercetare în domeniul temei

Înainte de a începe dezvoltarea aplicației a fost facută o cercetare amănunțită pentru a alege cele mai utilizate unități în mediul ingineriei. Având în vedere că sistemul internațional conține un număr de șapte unități fundamentale din care se pot deriva un număr foarte mare de unități derivate, în urma cercetării s-a ales un număr de nouă mărimi fizice și anume lungime, timp, viteză, forță, temperatură, masă, arie, informație și volum. Pentru fiecare dintre acestea s-a facut o cercetare și s-au selectat cele mai folosite unități de măsură.

Pentru obținerea valorilor de conversie s-au salvat valorile de pe mai multe site-uri deja existente și s-au comparat. Astfel am obținut valori de conversie cu o exactitate de până la 16 zecimale. De exemplu, pentru conversia forței din livre-forță în kilogram-forță am obținut valoarea 0.4539001648224489.

Creare proiect

În dezvoltarea proiectului s-au avut în vedere următoarele:

Aplicația trebuie să fie ușor de utilizat, să aibă o interfață ușor de înțeles și să fie compatibilă cu mai multe versiuni ale sistemului de operare Android.

Pasul 1:

În meniul Eclipse s-a creat un nou proiect : “File” ->”New” -> “Android Application Project”

Fig. 11 – Pasul 1 Creare Proiect

Pasul 2:

S-a introdus numele proiectului și al aplicației: „Convertor”,s-a selectat Minimum Required SDK și Target SDK. Aceste două câmpuri de fapt setează versiunea minimă a sistemului de operare Android pe care poate rula aplicația și versiunea pentru care este creată aceasta.

Fig. 12 – Pasul 2 Creare Proiect

Pasul 3: S-a configurat iconița aplicației.

Fig. 13 – Pasul 3 Creare Proiect

Pasul 4: Pentru a facilita schimbarea între tipul de unități de măsură s-a selectat tipul activității proiectului – „Navigation Drawer Activity”

Fig. 14 – Pasul 4 Creare Proiect

Pasul 5: S-au setat numele activității principale și a layout-urilor ca în imaginea următoare și se apasă „Finish”.

Fig. 15 – Pasul 5 Creare Proiect

Implementare cod și realizarea interfeței

Punctul de început al aplicației este MainActivity unde se încarcă datele în Navigation Drawer, se asignează event-urile și se setează fragmentul de început. Aici sunt definite și metoda de salvare a unei conversii și de înlocuire a fragmentului.

Activitatea principală are setat layout-ul “activity main” care conține :

Un FrameLayout unde vor fi încărcate fragmentele:

<FrameLayout

android:id="@+id/container"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

Un fragment – fragmentul de navigare:

<fragment

android:id="@+id/navigation_drawer"

android:name="com.example.convertor.NavigationDrawerFragment"

android:layout_width="@dimen/navigation_drawer_width"

android:layout_height="match_parent"

android:layout_gravity="start"

tools:layout="@layout/fragment_navigation_drawer"/>

Setarea layout-ului se face cu linia de cod : setContentView(R.layout.activity_main);

Pentru realizarea interfeței grafice a aplicației s-a creat un singur fragment care conține următoarele elemente:

Background customizat, imaginea aflându-se în directorul “drawable” în interiorul directorului “res” cu numele “background.png”

Un EditText de tipul numeric unde utilizatorul va introduce valoarea ce trebuie convertită

Două Spinnere în care se încarcă diferite liste de elemente pentru fiecare unitate de măsură. Primul reprezintă unitatea care trebuie convertită, iar cel de-al doilea reprezintă unitatea în care valoarea trebuie convertită

Un TextView care va fi setat la fiecare conversie cu rezultatul obținut din conversia valorii introduse în EditText.

În bara de meniu din partea de sus a ecranului se află două butoane și anume butonul care afișează lista unităților și butonul “Save” care salvează datele conversiei.

Cele nouă clase fragment se extind din clasa Fragment și au ca interfață layout-ul “fragment_fr”. Pentru fiecare clasă se setează un ArrayAdapter care încarcă în spinnerele denumite “s” și “s1” valorile care se află în liste statice în interiorul clasei “Utilities”:

ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_lungime);

dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)

s.setAdapter(dataAdapter);

s1.setAdapter(dataAdapter);

Fragment_lungime – adapterul ia valorile listei “valori_lungime” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_lungime);

În lista „valori_lungime” se încarcă următoarele valori ale unității de măsură lungime:

valori_lungime.add("Milimetri");

valori_lungime.add("Centimetri");

valori_lungime.add("Metri");

valori_lungime.add("Kilometri");

valori_lungime.add("Inci");

valori_lungime.add("Picioare");

valori_lungime.add("Mile");

valori_lungime.add("Yarzi");

Fragment_timp – adapterul ia valorile listei “valori_timp” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_timp);

În lista „valori_timp” se încarcă următoarele valori ale unității de măsură timp:

valori_timp.add("Nanosecunde");

valori_timp.add("Microsecunde");

valori_timp.add("Milisecunde");

valori_timp.add("Secunde");

valori_timp.add("Minute");

valori_timp.add("Ore");

valori_timp.add("Zile");

valori_timp.add("Saptamani");

valori_timp.add("Luni");

valori_timp.add("Semestre");

valori_timp.add("Ani");

valori_timp.add("Decenii");

valori_timp.add("Secole");

valori_timp.add("Milenii");

Fragment_viteză – adapterul ia valorile listei “valori_viteza” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_viteza);

În lista „valori_viteza” se încarcă următoarele valori ale unității de măsură viteză:

valori_viteza.add("m/s");

valori_viteza.add("m/min");

valori_viteza.add("m/h");

valori_viteza.add("km/s");

valori_viteza.add("km/min");

valori_viteza.add("km/h");

valori_viteza.add("ft/s");

valori_viteza.add("ft/min");

valori_viteza.add("ft/h");

valori_viteza.add("mps");

valori_viteza.add("mpm");

valori_viteza.add("mph");

valori_viteza.add("yd/s");

valori_viteza.add("yd/min");

valori_viteza.add("yd/h");

Fragment_forță – adapterul ia valorile listei “valori_forta” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_forta);

În lista „valori_forta” se încarcă urmatoarele valori ale unității de măsură forța:

valori_forta.add("Dyna(dyn)");

valori_forta.add("Kg-Forta(kgf)");

valori_forta.add("Kilopond(kp)");

valori_forta.add("Livre-Forta(lbf)");

valori_forta.add("Newtons(N)");

Fragment_temperatură – adapterul ia valorile listei “valori_temperatura” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_temperatura);

În lista „valori_temperatura” se încarcă următoarele valori ale unității de măsură temperatura:

valori_temperatura.add("Celsius – C");

valori_temperatura.add("Fahrenheit – F");

valori_temperatura.add("Kelvin – K");

valori_temperatura.add("Rankine – R");

Fragment_masă – adapterul ia valorile listei “valori_masa”:

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_masa);

În lista „valori_masa” se încarcă următoarele valori ale unității de măsură masa:

valori_masa.add("Miligrame(mg)");

valori_masa.add("Grame(g)");

valori_masa.add("Kilograme(Kg)");

valori_masa.add("Funte(lb)");

valori_masa.add("Uncii(oz-AV)");

valori_masa.add("Slug");

valori_masa.add("Tone(t)");

Fragment_arie – adapterul ia valorile listei “valori_arie” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_arie);

În lista „valori_arie” se încarcă următoarele valori ale unității de măsură arie:

valori_arie.add("Ari(a)");

valori_arie.add("Acri(ac)");

valori_arie.add("Centimetrii(cm²)");

valori_arie.add("Hectare(h)");

valori_arie.add("Kilometri(km²)");

valori_arie.add("Metri(m²)");

valori_arie.add("Yarzi(yd²)");

valori_arie.add("Picioare(ft²)");

Fragment_informație – adapterul ia valorile listei “valori_informatie” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_informatie);

În lista „valori_informatie” se încarcă următoarele valori ale unității de măsură informație:

valori_informatie.add("Biti");

valori_informatie.add("Bytes");

valori_informatie.add("KiloBytes");

valori_informatie.add("MegaBytes");

valori_informatie.add("GigaBytes");

valori_informatie.add("TerraBytes");

Fragment_volum – adapterul ia valorile listei “valori_volum” :

ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_volum);

În lista „valori_volum” se încarcă următoarele valori ale unității de măsură volum:

valori_volum.add("Mililitri");

valori_volum.add("Decilitri");

valori_volum.add("Centilitri");

valori_volum.add("Litri");

valori_volum.add("Decalitri");

valori_volum.add("Hectolitri");

valori_volum.add("Kilolitri");

valori_volum.add("Galon(UK)");

valori_volum.add("Galon(USA)");

Metodele care calculează și returnează valorile sunt apelate atunci când sunt detectate două tipuri de evenimente. Pentru a nu mai implementa un alt buton a cărui apăsare să apeleze metoda de calcul și de afișare a rezultatelor s-au folosit evenimentul de schimbare a textului și evenimentul de schimbare a valori selectate din spinner. Folosirea acestor evenimente a scăzut timpul de interacțiune, utilizatorul putând vizualiza rezultatul instant fară apăsarea unui alt buton ci doar prin introducerea sau schimbarea valorii sau a unitătii de masură.

TextWatcher a fost folosit pentru a supraveghea conținutul EditText-ului în timp ce utilizatorul introduce datele. Acesta permite ca fiecare modificare facută în EditText să fie tratată. Implementarea TextWatcher-ului este simplă,trebuie doar sa fie apelată metoda addTextChangedListener(). Dupa implementarea lui se creeaza automat trei tipuri de metode care pot trata evenimentul de modificare al EditText-ului.

public abstract void afterTextChanged (Editable s) : Această metodă este apelata atunci când textul a fost modificat,mai exact dupa ce a fost modificat.

beforeTextChanged (CharSequence s, start Int, int count, Int after) : Această metodă este apelată pentru a vă anunța că, în cadrul „s”, numărul caracterelor de „start” este pe cale să fie înlocuit cu un nou text cu lungimea „after”.

onTextChanged (CharSequence s, int start, int before, int count): Această metoda este apelată pentru a anunta că în cadrul ”s” numar caracterelor „start” au înlocuit vechiul text care avea lungimea „before”.

OnItemSelectedListener() este listener-ul pentru evenimentul de schimbare a elementului din spinner.

Metoda de calculare a rezultatului conversiei este apelată atunci când se detecteza evenimentul de schimbare al elementului pentru primul spinner cât și pentru cel de-al doilea. De asemenea mai este apelată în metoda „afterTextChanged()” a listener-ului de modificare de text.

public void afterTextChanged(Editable s)

{

try

{

valoare = value.getText().toString();

float valuee = Float.valueOf(value.getText().toString());

float rezultat = ut.CalculeazaMasa(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

rezultat_conv = String.format("%.3f", rezultat);

}

catch(Exception ex)

{

rezultat_conversie.setText("");

}

}

public void onItemSelected(AdapterView<?> parent, View view,

int position, long id) {

from = s.getSelectedItem().toString();

try

{

float valuee = Float.valueOf(value.getText().toString()); float rezultat = ut.CalculeazaMasa(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

}

catch(Exception ex)

{

rezultat_conversie.setText("");

}

}

Metode și algoritmi

Metode de calcul a valorilor

Mai sus am explicat cum se încarcă valorile în listele statice din interiorul clasei „Utilities.java”. În clasa „Utilities” s-au mai implementat alte nouă metode de calcul pentru valorile convertite.

Algoritmul de calcul a fost gândit astfel: pentru o conversie din kilometri în orice altă unitate de măsură pentru lungime era nevoie de șapte valori pentru transformarea în metri, yarzi, picioare,etc. De asemenea, pentru transformarea din yarzi în celelalte unități de măsură era nevoie de alte șapte valori ceea ce ar fi dus la un total de 8*7 valori, adică un total de 56 de valori care trebuiau memorate și aceasta doar pentru conversia din categoria „Lungime”, pentru „Timp” numărul de valori urcând la 182.

Pentru a evita acest algoritm care era foarte costisitor din punct de vedere al timpului, dar și al numărului mare de linii de cod care trebuiau scrise, în urma cercetării s-a implementat un algoritm care, de exemplu pentru „Lungime” a redus numărul de valori la un minim de 16, ceea ce ușurează mult munca. În algoritmul folosit se rețin valorile de conversie doar pentru o unitate, cum ar fi metru. Se memorează valorile pentru convertirea din metri în toate celelalte unități și un al doilea set de valori pentru convertirea tuturor celorlalte unități de măsură în metri.

Setul de valori este memorat într-o variabilă de tip „Map”. Această variabilă este aceeași cu variabilele de tip „Dictionary” din alte limbaje de programare, ea fiind o structură de date constând într-un set de chei și valori în care fiecare cheie este mapată la o singură valoare. Cheia și valoarea pot avea orice tip de date și nu trebuie să fie același. Pentru memorarea valorilor s-a folosit o cheie de tip String care reprezintă tipul de unitate de măsură, iar valoarea este de tip Float și reprezintă numărul real cu ajutorul căruia se face conversia.

Metoda de calcul primește 3 parametri :

unit_from – reprezintă unitatea din care se va face conversia

unit_to – reprezintă unitatea în care se va face conversia

value – valoarea ce trebuie convertită

publicfloat CalculeazaLungime(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromMeter = new HashMap<String,Float>();

fromMeter.put("Milimetri", (float) 1000);

fromMeter.put("Centimetri", (float) 100);

fromMeter.put("Metri", (float) 1);

fromMeter.put("Kilometri", (float) 0.001);

fromMeter.put("Inci", (float) 39.37);

fromMeter.put("Picioare", (float) 3.281);

fromMeter.put("Mile", (float) 0.000621);

fromMeter.put("Yarzi", (float) 1.093);

Map<String,Float> toMeter = new HashMap<String,Float>();

toMeter.put("Milimetri", (float) 0.001);

toMeter.put("Centimetri", (float) 0.01);

toMeter.put("Metri", (float) 1);

toMeter.put("Kilometri", (float) 1000);

toMeter.put("Inci", (float) 0.0254);

toMeter.put("Picioare", (float) 0.3048);

toMeter.put("Mile", (float) 1609.34);

toMeter.put("Yarzi", (float) 0.9144);

try

{

float a = toMeter.get(unit_from);

float b = fromMeter.get(unit_to);

rezultat = value * a * b;

}

catch(Exception ex)

{

ex.printStackTrace();

}

return rezultat;

}

Cele două variabile de tip Map sunt „toMeter” și „fromMeter”.

Cu ajutorul „toMeter” se obține numărul întreg necesar convertirii din valoarea primită ca parametru prin „unit_from” în unitatea de măsură metri, iar cu „fromMeter” se obține numărul întreg necesar convertirii în valoarea care este primită prin parametrul „unit_to”.

Obținerea numărului întreg se face cu metoda „Get” căreia îi trebuie specificată cheia de la care trebuie extrasă valoarea.

În variabila „a” se salvează numărul pentru conversia în metri :

float a = toMeter.get(unit_from);

În variabila „b” se salvează numărul pentru conversia din metri în unitatea de măsură cerută:

float b = fromMeter.get(unit_to);

Rezultatul final se obține prin înmulțirea valorii primite ca parametru cu „a” și apoi cu „b”.

La fel ca pentru măsurarea lungimii pentru fiecare mărime fizică s-a selectat o unitate de măsură ca unitate de trecere astfel :

Metoda de înlocuire a fragmentelor

Metoda „replaceFragment()” este folosită pentru a înlocui fragmentele. Parametrul primit este de tip Fragment și este apelat atunci când este apăsată una din valorile din bara de navigare (NavigationDrawer).

publicvoid replaceFragment(Fragment fragment) {

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.container, fragment, fragment.toString());

fragmentTransaction.addToBackStack(fragment.toString());

fragmentTransaction.commit();

}

Obiectul fragmentTransaction este un obiect de tip fragmentManager.beginTransaction()care la rândul lui este un obiect de tipul FragmentManager.

Linia „fragmentTransaction.replace(R.id.container, fragment, fragment.toString());” încarcă fragmentul specificat în FrameLayout-ul cu id-ul R.id.container care se află în activity_main.xml, dar acțiunea are loc abia atunci când este executată ultima linie de cod a metodei, atunci când este apelată metoda „commit()”.

Metoda de salvare a conversiei

Metoda „SaveConversion” este apelată atunci când este apăsat butonul „Save”. Această metodă are următoarea structură:

publicstaticlong SaveConversion(String categorie,String from,String to,String value,String rezultat)

{

long result;

result = mySQLiteAdapter.SaveConversion(categorie, from, to, value, rezultat);

return result;

}

În interiorul acestei metode este apelată o metodă din clasa SQLiteAdapter, care face o operație de inserare în baza de date. Metoda „SaveConversion” este la randul ei apelată din clasa „NavigationDrawerFragment.java” care o apelează cu diferiți parametri în funcție de fragmentul care este activ și de valorile introduse și selectate de către utilizator.

Tipul acestei metode este „long” deoarece rezultatul inserării este așa, query-ul returnând numărul coloanei afectate sau valoarea -1 în cazul în care nu s-a putut face inserarea. Această valoare este folosită pentru a anunța utilizatorul dacă a reușit sau nu salvarea datelor, un mesaj sub formă de Toast este afișat utilizatorului. Această verificare se face astfel :

if(rez> 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

Un toast este un pop-up care oferă o informație utilizatorului. Se apelează cu proprietatea makeText() în care trebuie specificat contextul în care este afișat acesta, mesajul și durata. Toast-ul dispare automat după o perioada de timp.

Metoda de încărcare a datelor în ListView

Numele acestei metode este „IncarcareLista()”. Nu primește niciun parametru pentru că nu are nevoie și nici nu returnează nimic. Singura funcționalitate este aceea de a încărca informațiile extrase din baza de date într-o listă care este afișată utilizatorului. Corpul funcției este:

Private void IncarcaLista() {

try

{

String x= mySQLiteAdapter.GetAllConversions();

String[] listParts = null;

listParts = x.split("~");

lista = new ArrayList<String>();

for(int j = 0; j< listParts.length;j++)

{

lista.add(listParts[j]);

}

for (int i = 0; i <lista.size(); i++) {

LayoutInflater inflater = null;

inflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View mLinearView = inflater.inflate(R.layout.conversii_row, null);

TextView valoare_din = (TextView) mLinearView.findViewById(R.id.txtFromValue);

TextView unitate_din = (TextView) mLinearView.findViewById(R.id.txtFromUnit);

TextView valoare_in = (TextView) mLinearView.findViewById(R.id.txtToValue);

TextView unitate_in = (TextView) mLinearView.findViewById(R.id.txtToUnit);

String disParts[] = null;

disParts = lista.get(i).toString().split(";");

valoare_din.setText(disParts[0].toString());

unitate_din.setText(disParts[1].toString());

valoare_in.setText(disParts[2].toString());

unitate_in.setText(disParts[3].toString());

mLinearListView.addView(mLinearView)

}

}

catch(Exception e)

{

e.printStackTrace();

}

}

Pentru realizarea interfeței de afișare a informațiilor extrase din baza de date s-au folosit două fișiere xml: „show_conversii.xml” și „conversii_row.xml”. Primul fișier conține două elemente: Titlul paginii și o listă liniară în care se încarcă un layout liniar, orientat orizontal care conține 4 TextView-uri și care se află în cel de-al doilea fișier.

Elemente „show_conversii.xml” :

<TextView

android:id="@+id/txtTittle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="5dp"

android:layout_centerHorizontal="true"

android:text="Conversii salvate"

android:textColor="#000000"

android:textSize="25sp"

android:textAppearance="?android:attr/textAppearanceLarge"/>

<LinearLayout

android:id="@+id/linear_scroll"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical">

<LinearLayout

android:id="@+id/linear_listview"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_marginTop="15dp"/>

Elemente „conversii_row.xml” :

<TextView

android:id="@+id/txtFromValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginLeft="10dp"

android:textSize="18sp"

android:textStyle="bold"

android:textColor="#000000"

android:text="1"/>

<TextView

android:id="@+id/txtFromUnit"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="20sp"

android:layout_marginLeft="5dp"

android:textColor="#000000"

android:text="2"/>

<TextView

android:id="@+id/txtequals"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="20sp"

android:layout_marginLeft="5dp"

android:textColor="#000000"

android:text=" = "/>

<TextView

android:id="@+id/txtToValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginLeft="10dp"

android:textSize="18sp"

android:textStyle="bold"

android:textColor="#000000"

android:text="1"/>

Valorile obținute în vectorul disParts prin linia :

disParts = lista.get(i).toString().split(";"); se încarcă în TextView-urile din fișierul conversii_row.xml și vor fi afișate având formatul:

valoare introdusă + unitate de măsură + „=” + valoare obținută în urma conversiei + unitatea în care a fost convertită.

Linia de cod care face încărcarea valorilor înregistrate în elementele LinearLayout-ului din „conversii_row” în lista liniară din „show_conversii” este: mLinearListView.addView(mLinearView);

Această secvență de instrucțiuni se execută pentru fiecare rând din rezultatul obținut din baza de date prin linia de cod:for (int i = 0; i <lista.size(); i++).

Baza de date a aplicației

Pentru crearea bazei de date a aplicației s-a folosit librăria SQLite. Pentru aplicația noastră, vom detalia folosirea bazelor de date SQLite. Pe telefoane, la ora actuală, este implementat SQLite versiunea 3.

Interacțiunea cu bazele de date SQLite se face sub formă de query. Aceste query-uri nu diferă foarte mult față de cele din SQL. Ceea ce este diferit la ele este tipul de date al coloanelor. Tipul de date „text” este același cu tipul de date „varchar” din SQL.

Query-ul pentru creara unui tabel în baza de date are următoarea structură:

„create table + <nume_tabel>(<nume coloana><tipul de date al coloanei><constrangeri>)”

Cele mai folosite constrângeri sunt :

Primary key : este folosit pentru a identifica în mod unic linile din tabel

Not null :  specifică faptul că acestă coloană nu poate conține elemente cu valoarea null

Foreign key sau cheie externă este un câmp al unui tabel prin care se completează o relație identificând tabela părinte. O cheie externă stabilește o relație sau o constrângere între două tabele.

Autoincrement : specifică cheii primare să își incrementeze automat valoarea atunci când o linie nouă este introdusă în baza de date

Pentru baza de date a aplicației s-a creat un singur tabel cu numele “tblConversii” care are șase coloane. Structura tabelului este prezentată în tabelul următor:

Query-ul pentru crearea bazei de date este următorul : "create table if not exists tblConversie(id_conversie integer primary key autoincrement,categorie text not null,conversie_din text not null,conversie_in text not null,valoare text not null,rezultat_conversie text not null);”

Pentru a putea scrie sau a citi informații din baza de date a fost nevoie de implementarea a două metode : openToRead() și openToWrite(). În interiorul fiecărei metode un obiect de tipul SQLiteHelper apelează getReadableDatabase(), respectiv getWritableDatabase().

Ambele metode creează sau deschid o bază de date care va fi folosită pentru citire sau scriere. Prima dată când este apelată una din aceste metode baza de date se va deschide și onCreate() și onUpgrade() vor fi apelate.

public SQLiteAdapter openToRead() throws android.database.SQLException {

sqLiteHelper = newSQLiteHelper(context, MYDATABASE_NAME, null,

MYDATABASE_VERSION);

sqLiteDatabase = sqLiteHelper.getReadableDatabase();

returnthis;

}

public SQLiteAdapter openToWrite() throws android.database.SQLException {

sqLiteHelper = newSQLiteHelper(context, MYDATABASE_NAME, null,

MYDATABASE_VERSION);

sqLiteDatabase = sqLiteHelper.getWritableDatabase();

returnthis;

}

Fără ca una din aceste două metode să fie apelată, celelalte nu ar funcționa deoarece baza de date nu ar exista. După ce baza de date a fost creată se pot insera informații în tabel. Metoda de inserare a datelor se numeste „SaveConversion”:

publiclong SaveConversion(String categorie,String from,String to,String value,String rezultat)

{

long ret = 0;

ContentValues contentValues = new ContentValues();

contentValues.put(KEY_categorie, categorie);

contentValues.put(KEY_unitFrom, from);

contentValues.put(KEY_unitTo, to);

contentValues.put(KEY_Value, value);

contentValues.put(KEY_rezultat_conversie, rezultat);

try {

ret = sqLiteDatabase.insert(Tabel_Conversie, null,

contentValues);

} catch (SQLException e) {

e.printStackTrace();

ret = 0;

}

return ret;

}

Tipul metodei este long deoarece rezultatul inserării se memorează în variabila „rez” de tip long. Dacă inserarea este facută cu succes, variabila va lua valoarea coloanei noi inserate, în caz contrar va lua valoarea -1.

Pentru inserarea valorilor se folosește un obiect ContentValues și metoda „put()” care primește ca parametrii cheia reprezentând coloana tabelului și valoarea ce va fi inserată în coloana respectivă. Pentru chei au fost declarate stringuri statice pentru a putea fi folosite și în alte metode:

Public static final String KEY_ID_conversie = "id_converse";

Public static final String KEY_categorie = "categorie";

Public static final String KEY_unitFrom = "conversie_din";

Public static final String KEY_unitTo= "conversie_in";

Public static final String KEY_Value = "valoare";

Public static final String KEY_rezultat_conversie = "rezultat_conversie";

Ultima metodă folosită este cea de citire a tuturor informațiilor salvate în baza de date. Numele acestei metode este „GetAllConversions()” și are următoarea structură:

public String GetAllConversions()

{

String rezultat_conversii = "";

String[] columns = new String[] { KEY_Value, KEY_unitFrom, KEY_rezultat_conversie, KEY_unitTo };

Cursor cursor = sqLiteDatabase.query(Tabel_Conversie, columns,

null, null, null, null, null);

for (cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()) {

for (int i = 0; i < columns.length; i++) {

rezultat_conversii = rezultat_conversii + cursor.getString(i) + ";";

}

rezultat_conversii += "~";

}

return rezultat_conversii;

}

Numele coloanelor din care trebuie selectată informația sunt memorate în vectorul „columns”. Pentru obținerea și parcurgerea rezultatelor se folosește un obiect Cursor care selectează fiecare coloană. Cu iterația din interiorul funcției „for” se memorează în stringul „rezultat_conversii” fiecare valoare a coloanelei selectate.Valorile de pe un singur rând sunt separate între ele prin caracterul „ ; ” iar rândurile sunt separate prin caracterul „~”. Aceste caractere sunt cele care vor face separarea rezultatelor pentru a fi afișate.

Afișarea valorilor în format matematic

Afișarea datelor a fost una din problemele întâlnite de-a lungul implementării soluției. În dorința de a obține valori cât mai exacte, valorile de conversie având un numar mai mare de zecimale, datele obținute în urma conversiei erau afișate în format științific. Afișează un număr în notație exponențială, înlocuind o parte a numărului cu E+n, unde E (de la Exponent) înmulțește numărul precedent cu 10 la puterea n. De exemplu, formatul științific cu două zecimale afișează 12345678901 ca 1,23E+10, însemnând 1,23.

Utilizatorii acestei aplicații fiind din diferite domenii au nevoie de numere care să fie afișate într-un format cât mai general cu un număr de zecimale nu foarte mare. Pentru a afișa numerele în formatul dorit s-a folosit metoda „.format” a clasei String. Convertește valoarea dată ca parametru la șiruri de caractere pe baza formatelor specificate și le introduce într-un alt șir.

Exemplu pentru mărimea fizică lungime :

float rezultat = ut.CalculeazaLungime(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

Se observă că formatul folosit este unul de tip float cu trei zecimale.

Manual de utilizare

Manual de utilizare al aplicației este de fapt descrierea funcțională.

Pasul 1:

La deschiderea aplicației se încarcă automat primul fragment. De aici utilizatorul are la dispoziție următoarele acțiuni:

apasă butonul de afișare a barei ()de navigare

introduce valoarea care dorește să fie convertită

selectează unitățile de măsura dorite

salvează o conversie finalizată.

Fig. 16 – Instrucțiuni de utilizare 1

Pasul 2:

Dacă acțiunea făcută de utilizator a fost “A.” după afișarea barei de navigare opțiunile sunt următoarele:

Apăsare buton pentru închiderea barei de navigare și revenirea la meniul anterior

Selectare măsură fizică pentru conversie

Selectare vizualizare conversii salvate

Fig. 17 – Instrucțiuni de utilizare 2

Selectarea opțiunii “A” sau “B” de la “face ca utilizarea aplicației să se reia de la “Pasul 1”, iar selectarea opțiunii “C” duce utilizatorul în “Pasul 3”.

Pasul 3:

În acest meniu utilizatorul poate vizualiza lista cu toate conversiile salvate și singura acțiune pe care o poate face este de a apăsa pe butonul de afișare a barei de navigare și să reia acțiunile de la “Pasul 2”.

Fig. 18 – Instrucțiuni de utilizare 3

Concluzii

Scopul acestui proiect a fost realizarea unei aplicații de conversie a principalelor unitați de masură folosite in sistemul internațional,care să ruleze pe sistemul de operare Android. Pe parcursul dezvoltării am reușit sa ne îmbunatațim cunoștiințele inginerești și capabilitatea de a lucra in echipă. Deși am întâlnit diverse probleme tehnice,împreuna cu colegul meu am reușit să găsim cea mai optimă soluție din punct de vedere al timpului si al resurselor aplicației.

Rezultatul obținut a fost cel așteptat și ne-a motivat ca pe viitor să îmbunătățim performanțele acestei aplicații și chiar dezvoltarea altor aplicatii mai complexe.

Bibliografie

[GN13] – Android Design Patterns: Interaction Design Solutions for Developers, Greg Nudelman, 2013

[IC13] – Android User Interface Design: Turning Ideas and Sketches into Beautifully Designed Apps, Ian G. Clifton, 2013

[ZM11]Programming Android, Zigurd Mednieks, Laird Dornin, G. Blake Meike & Masumi Nakamura,2011

Referinte web

[SQLite] – Documentatie SQLite,disponibila on-line la adresa :

https://www.sqlite.org/docs.html

[ANDROID] – Android,diponibil on-line la adresa:

https://ro.wikipedia.org/wiki/Android_(sistem_de_operare)

[DA] – Dezvoltare android,disponibil on-line la adresa

http://developer.android.com/reference/android/app/Activity.html

[AA] – Arhitectura android,diponibila on-line la adresa:

http://ocw.cs.pub.ro/courses/pdsd/labs/00

[CDA] – Configurare mediu de dezvoltare android, disponibil on-line la adresa:

http://www.instructables.com/id/How-To-Setup-Eclipse-for-Android-App-Development/?ALLSTEPS

Anexe

Clasa MainActivity:

public class MainActivity extends ActionBarActivity

implements NavigationDrawerFragment.NavigationDrawerCallbacks {

private static SQLiteAdapter mySQLiteAdapter;

private NavigationDrawerFragment mNavigationDrawerFragment;

public static CharSequence mTitle;

public static int fragment_nr;

Fragment fr;

FragmentManager fm;

FragmentTransaction fragmentTransaction;

Utilities ut = new Utilities();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mySQLiteAdapter = new SQLiteAdapter(this);

mySQLiteAdapter.openToWrite();

mNavigationDrawerFragment = (NavigationDrawerFragment)

getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);

ListView mDrawerList = (ListView) findViewById(R.id.lista_optiuni);

mTitle = getTitle();

DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

// Set up the drawer.

mNavigationDrawerFragment.setUp(

R.id.navigation_drawer,

(DrawerLayout) findViewById(R.id.drawer_layout));

}

public static long SaveConversion(String categorie,String from,String to,String value,String rezultat)

{

long result;

result = mySQLiteAdapter.SaveConversion(categorie, from, to, value, rezultat);

return result;

}

public void replaceFragment(Fragment fragment) {

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

fragmentTransaction.replace(R.id.container, fragment, fragment.toString());

fragmentTransaction.addToBackStack(fragment.toString());

fragmentTransaction.commit();

}

@Override

public void onNavigationDrawerItemSelected(int position) {

// update the main content by replacing fragments

FragmentManager fragmentManager = getSupportFragmentManager();

fragmentManager.beginTransaction()

.replace(R.id.container, PlaceholderFragment.newInstance(position + 1))

.commit();

}

public void onSectionAttached(int number) {

switch (number) {

case 1:

mTitle = "Lungime";

fragment_nr = 1;

fr = new fragment_lungime();

replaceFragment(fr);

break;

case 2:

mTitle = "Timp";

fragment_nr = 2;

fr = new fragment_timp();

replaceFragment(fr);

break;

case 3:

mTitle = "Viteza";

fragment_nr = 3;

fr = new fragment_viteza();

replaceFragment(fr);

break;

case 4:

mTitle = "Forta";

fragment_nr = 4;

fr = new fragment_forta();

replaceFragment(fr);

break;

case 5:

mTitle = "Temperatura";

fragment_nr = 5;

fr = new fragment_temperatura();

replaceFragment(fr);

break;

case 6:

mTitle = "Masa";

fragment_nr = 6;

fr = new fragment_masa();

replaceFragment(fr);

break;

case 7:

mTitle = "Arie";

fragment_nr = 7;

fr = new fragment_arie();

replaceFragment(fr);

break;

case 8:

mTitle = "Informatie";

fragment_nr = 8;

fr = new fragment_informatie();

replaceFragment(fr);

break;

case 9:

mTitle = "Volum";

fragment_nr = 9;

fr = new fragment_volum();

replaceFragment(fr);

break;

case 10:

mTitle = "Conversii salvate";

fr = new fragment_conversii();

replaceFragment(fr);

break;

}

}

public void restoreActionBar() {

ActionBar actionBar = getSupportActionBar();

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);

actionBar.setDisplayShowTitleEnabled(true);

actionBar.setTitle(mTitle);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

if (!mNavigationDrawerFragment.isDrawerOpen()) {

getMenuInflater().inflate(R.menu.main, menu);

restoreActionBar();

return true;

}

return super.onCreateOptionsMenu(menu);

}

public static class PlaceholderFragment extends Fragment {

private static final String ARG_SECTION_NUMBER = "section_number";

public static PlaceholderFragment newInstance(int sectionNumber) {

PlaceholderFragment fragment = new PlaceholderFragment();

Bundle args = new Bundle();

args.putInt(ARG_SECTION_NUMBER, sectionNumber);

fragment.setArguments(args);

return fragment;

}

public PlaceholderFragment() {

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.show_conversii, container, false);

return rootView;

}

@Override

public void onAttach(Activity activity) {

super.onAttach(activity);

((MainActivity) activity).onSectionAttached(

getArguments().getInt(ARG_SECTION_NUMBER));

}

}

}

Clasa NavigationDrawerFragment:

private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";

private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";

private NavigationDrawerCallbacks mCallbacks;

private ActionBarDrawerToggle mDrawerToggle;

private DrawerLayout mDrawerLayout;

private ListView mDrawerListView;

private View mFragmentContainerView;

private int mCurrentSelectedPosition = 0;

private boolean mFromSavedInstanceState;

private boolean mUserLearnedDrawer;

public NavigationDrawerFragment() {

}

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Read in the flag indicating whether or not the user has demonstrated awareness of the

// drawer. See PREF_USER_LEARNED_DRAWER for details.

SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());

mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);

if (savedInstanceState != null) {

mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);

mFromSavedInstanceState = true;

}

// Select either the default item (0) or the last selected item.

selectItem(mCurrentSelectedPosition);

}

@Override

public void onActivityCreated (Bundle savedInstanceState) {

super.onActivityCreated(savedInstanceState);

// Indicate that this fragment would like to influence the set of actions in the action bar.

setHasOptionsMenu(true);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

mDrawerListView = (ListView) inflater.inflate(

R.layout.fragment_navigation_drawer, container, false);

mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

selectItem(position);

}

});

mDrawerListView.setAdapter(new ArrayAdapter<String>(

getActionBar().getThemedContext(),

android.R.layout.simple_list_item_1,

android.R.id.text1,

new String[]{

"Lungime",

"Timp",

"Viteza",

"Forta",

"Temperatura",

"Masa",

"Arie",

"Informatie",

"Volum",

"Conversii salvate",

}));

mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);

return mDrawerListView;

}

public boolean isDrawerOpen() {

return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);

}

public void setUp(int fragmentId, DrawerLayout drawerLayout) {

mFragmentContainerView = getActivity().findViewById(fragmentId);

mDrawerLayout = drawerLayout;

// set a custom shadow that overlays the main content when the drawer opens

mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);

// set up the drawer's list view with items and click listener

ActionBar actionBar = getActionBar();

actionBar.setDisplayHomeAsUpEnabled(true);

actionBar.setHomeButtonEnabled(true);

// ActionBarDrawerToggle ties together the the proper interactions

// between the navigation drawer and the action bar app icon.

mDrawerToggle = new ActionBarDrawerToggle(

getActivity(), /* host Activity */

mDrawerLayout, /* DrawerLayout object */

R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */

R.string.navigation_drawer_open, /* "open drawer" description for accessibility */

R.string.navigation_drawer_close /* "close drawer" description for accessibility */

) {

@Override

public void onDrawerClosed(View drawerView) {

super.onDrawerClosed(drawerView);

if (!isAdded()) {

return;

}

getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()

}

@Override

public void onDrawerOpened(View drawerView) {

super.onDrawerOpened(drawerView);

if (!isAdded()) {

return;

}

if (!mUserLearnedDrawer) {

// The user manually opened the drawer; store this flag to prevent auto-showing

// the navigation drawer automatically in the future.

mUserLearnedDrawer = true;

SharedPreferences sp = PreferenceManager

.getDefaultSharedPreferences(getActivity());

sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).commit();

}

getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()

}

};

// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,

// per the navigation drawer design guidelines.

if (!mUserLearnedDrawer && !mFromSavedInstanceState) {

mDrawerLayout.openDrawer(mFragmentContainerView);

}

// Defer code dependent on restoration of previous instance state.

mDrawerLayout.post(new Runnable() {

@Override

public void run() {

mDrawerToggle.syncState();

}

});

mDrawerLayout.setDrawerListener(mDrawerToggle);

}

private void selectItem(int position) {

mCurrentSelectedPosition = position;

if (mDrawerListView != null) {

mDrawerListView.setItemChecked(position, true);

}

if (mDrawerLayout != null) {

mDrawerLayout.closeDrawer(mFragmentContainerView);

}

if (mCallbacks != null) {

mCallbacks.onNavigationDrawerItemSelected(position);

}

}

@Override

public void onAttach(Activity activity) {

super.onAttach(activity);

try {

mCallbacks = (NavigationDrawerCallbacks) activity;

} catch (ClassCastException e) {

throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");

}

}

@Override

public void onDetach() {

super.onDetach();

mCallbacks = null;

}

@Override

public void onSaveInstanceState(Bundle outState) {

super.onSaveInstanceState(outState);

outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);

}

@Override

public void onConfigurationChanged(Configuration newConfig) {

super.onConfigurationChanged(newConfig);

// Forward the new configuration the drawer toggle component.

mDrawerToggle.onConfigurationChanged(newConfig);

}

@Override

public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {

// If the drawer is open, show the global app actions in the action bar. See also

// showGlobalContextActionBar, which controls the top-left area of the action bar.

if (mDrawerLayout != null && isDrawerOpen()) {

inflater.inflate(R.menu.global, menu);

showGlobalContextActionBar();

}

super.onCreateOptionsMenu(menu, inflater);

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

if (mDrawerToggle.onOptionsItemSelected(item)) {

return true;

}

if(item.getItemId() == R.id.action_example)

{

switch (MainActivity.fragment_nr) {

case 1:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_lungime.from, fragment_lungime.to, fragment_lungime.valoare, fragment_lungime.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 2:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_timp.from, fragment_timp.to, fragment_timp.valoare, fragment_timp.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 3:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_viteza.from, fragment_viteza.to, fragment_viteza.valoare, fragment_viteza.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 4:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_forta.from, fragment_forta.to, fragment_forta.valoare, fragment_forta.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 5:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_temperatura.from, fragment_temperatura.to, fragment_temperatura.valoare, fragment_temperatura.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 6:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_masa.from, fragment_masa.to, fragment_masa.valoare, fragment_masa.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 7:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_arie.from, fragment_arie.to, fragment_arie.valoare, fragment_arie.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 8:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_informatie.from, fragment_informatie.to, fragment_informatie.valoare, fragment_informatie.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

case 9:

rez = MainActivity.SaveConversion(MainActivity.mTitle.toString(), fragment_volum.from, fragment_volum.to, fragment_volum.valoare, fragment_volum.rezultat_conv);

if(rez > 0)

{

Toast.makeText(getActivity(), "Conversia a fost salvata!", Toast.LENGTH_LONG).show();

}

else

{

Toast.makeText(getActivity(), "Conversia nu a putut fi salvata!", Toast.LENGTH_LONG).show();

}

break;

}

}

return super.onOptionsItemSelected(item);

}

private void showGlobalContextActionBar() {

ActionBar actionBar = getActionBar();

actionBar.setDisplayShowTitleEnabled(true);

actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);

actionBar.setTitle(R.string.app_name);

}

private ActionBar getActionBar() {

return ((ActionBarActivity) getActivity()).getSupportActionBar();

}

public static interface NavigationDrawerCallbacks {

void onNavigationDrawerItemSelected(int position);

}

}

Clasa Utilities:

public class Utilities {

static List <String> valori_lungime = new ArrayList<String>();

static List <String> valori_timp = new ArrayList<String>();

static List <String> valori_viteza = new ArrayList<String>();

static List <String> valori_forta = new ArrayList<String>();

static List <String> valori_temperatura = new ArrayList<String>();

static List <String> valori_masa = new ArrayList<String>();

static List <String> valori_arie = new ArrayList<String>();

static List <String> valori_volum = new ArrayList<String>();

static List <String> valori_informatie = new ArrayList<String>();

public Utilities() {

IncarcareValoriLungime();

IncarcareValoriTimp();

IncarcareValoriViteza();

IncarcareValoriForta();

IncarcareValoriTemperatura();

IncarcareValoriMasa();

IncarcareValoriArie();

IncarcareValoriInformatie();

IncarcareValoriVolum();

}

private void IncarcareValoriLungime()

{

valori_lungime.clear();

valori_lungime.add("Milimetri");

valori_lungime.add("Centimetri");

valori_lungime.add("Metri");

valori_lungime.add("Kilometri");

valori_lungime.add("Inci");

valori_lungime.add("Picioare");

valori_lungime.add("Mile");

valori_lungime.add("Yarzi");

}

private void IncarcareValoriTimp()

{

valori_timp.clear();

valori_timp.add("Nanosecunde");

valori_timp.add("Microsecunde");

valori_timp.add("Milisecunde");

valori_timp.add("Secunde");

valori_timp.add("Minute");

valori_timp.add("Ore");

valori_timp.add("Zile");

valori_timp.add("Saptamani");

valori_timp.add("Luni");

valori_timp.add("Semestre");

valori_timp.add("Ani");

valori_timp.add("Decenii");

valori_timp.add("Secole");

valori_timp.add("Milenii");

}

private void IncarcareValoriViteza()

{

valori_viteza.clear();

valori_viteza.add("m/s");

valori_viteza.add("m/min");

valori_viteza.add("m/h");

valori_viteza.add("km/s");

valori_viteza.add("km/min");

valori_viteza.add("km/h");

valori_viteza.add("ft/s");

valori_viteza.add("ft/min");

valori_viteza.add("ft/h");

valori_viteza.add("mps");

valori_viteza.add("mpm");

valori_viteza.add("mph");

valori_viteza.add("yd/s");

valori_viteza.add("yd/min");

valori_viteza.add("yd/h");

}

private void IncarcareValoriForta()

{

valori_forta.clear();

valori_forta.add("Dyna(dyn)");

valori_forta.add("Kg-Forta(kgf)");

valori_forta.add("Kilopond(kp)");

valori_forta.add("Livre-Forta(lbf)");

valori_forta.add("Newtons(N)");

}

private void IncarcareValoriTemperatura()

{

valori_temperatura.clear();

valori_temperatura.add("Celsius – C");

valori_temperatura.add("Fahrenheit – F");

valori_temperatura.add("Kelvin – K");

valori_temperatura.add("Rankine – R");

}

private void IncarcareValoriMasa()

{

valori_masa.clear();

valori_masa.add("Miligrame(mg)");

valori_masa.add("Grame(g)");

valori_masa.add("Kilograme(Kg)");

valori_masa.add("Funte(lb)");

valori_masa.add("Uncii(oz-AV)");

valori_masa.add("Slug");

valori_masa.add("Tone(t)");

}

private void IncarcareValoriArie()

{

valori_arie.clear();

valori_arie.add("Ari(a)");

valori_arie.add("Acri(ac)");

valori_arie.add("Centimetrii(cm²)");

valori_arie.add("Hectare(h)");

valori_arie.add("Kilometri(km²)");

valori_arie.add("Metri(m²)");

valori_arie.add("Yarzi(yd²)");

valori_arie.add("Picioare(ft²)");

}

private void IncarcareValoriInformatie()

{

valori_informatie.clear();

valori_informatie.add("Biti");

valori_informatie.add("Bytes");

valori_informatie.add("KiloBytes");

valori_informatie.add("MegaBytes");

valori_informatie.add("GigaBytes");

valori_informatie.add("TerraBytes");

}

private void IncarcareValoriVolum()

{

valori_volum.clear();

valori_volum.add("Mililitri");

valori_volum.add("Decilitri");

valori_volum.add("Centilitri");

valori_volum.add("Litri");

valori_volum.add("Decalitri");

valori_volum.add("Hectolitri");

valori_volum.add("Kilolitri");

valori_volum.add("Galon(UK)");

valori_volum.add("Galon(USA)");

}

public float CalculeazaLungime(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromMeter = new HashMap<String,Float>();

fromMeter.put("Milimetri", (float) 1000);

fromMeter.put("Centimetri", (float) 100);

fromMeter.put("Metri", (float) 1);

fromMeter.put("Kilometri", (float) 0.001);

fromMeter.put("Inci", (float) 39.37);

fromMeter.put("Picioare", (float) 3.281);

fromMeter.put("Mile", (float) 0.000621);

fromMeter.put("Yarzi", (float) 1.093);

Map<String,Float> toMeter = new HashMap<String,Float>();

toMeter.put("Milimetri", (float) 0.001);

toMeter.put("Centimetri", (float) 0.01);

toMeter.put("Metri", (float) 1);

toMeter.put("Kilometri", (float) 1000);

toMeter.put("Inci", (float) 0.0254);

toMeter.put("Picioare", (float) 0.3048);

toMeter.put("Mile", (float) 1609.34);

toMeter.put("Yarzi", (float) 0.9144);

try

{

float a = toMeter.get(unit_from);

float b = fromMeter.get(unit_to);

rezultat = value * a * b;

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaTimp(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromMinute = new HashMap<String,Float>();

fromMinute.put("Nanosecunde", Float.valueOf(60000000*1000));

fromMinute.put("Microsecunde", (float)(60000000));

fromMinute.put("Milisecunde", (float) 60000);

fromMinute.put("Secunde", (float) 60);

fromMinute.put("Minute", (float) 1);

fromMinute.put("Ore", (float) 0.0166666667);

fromMinute.put("Zile", (float) 0.000694);

fromMinute.put("Saptamani", (float) 0.000099206);

fromMinute.put("Luni", (float) 0.000022831);

fromMinute.put("Semestre", (float) (0.000022831 * 6));

fromMinute.put("Ani", (float) 0.00000190258);

fromMinute.put("Decenii", (float) ((float) 1.902587519026 * Math.pow(10, -7)));

fromMinute.put("Secole", (float) ((float) 1.902587519026 * Math.pow(10, -8)));

fromMinute.put("Milenii", (float) ((float) 1.902587519026 * Math.pow(10, -9)));

Map<String,Float> toMinute = new HashMap<String,Float>();

toMinute.put("Nanosecunde", (float) ((float) 1.666666666667 * Math.pow(10, -11)));

toMinute.put("Microsecunde", (float) ((float) 1.666666666667 * Math.pow(10, -8)));

toMinute.put("Milisecunde", (float) 0.00001666666666667);

toMinute.put("Secunde", (float) 0.01666666666667);

toMinute.put("Minute", (float) 1);

toMinute.put("Ore", (float) 60);

toMinute.put("Zile", (float) 1440);

toMinute.put("Saptamani", (float) 10080);

toMinute.put("Luni", (float) 43800);

toMinute.put("Semestre", (float) (43800 * 6));

toMinute.put("Ani", (float) 525600);

toMinute.put("Decenii", (float) 5256000);

toMinute.put("Secole", (float) 52560000);

toMinute.put("Milenii", (float) 525600000);

try

{

float a = toMinute.get(unit_from);

float b = fromMinute.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaViteza(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromMeter = new HashMap<String,Float>();

fromMeter.put("m/s", (float) 1);

fromMeter.put("m/min", (float) 60);

fromMeter.put("m/h", (float) 3600);

fromMeter.put("km/s", (float) 0.001);

fromMeter.put("km/min", (float) 0.06);

fromMeter.put("km/h", (float) 3.6);

fromMeter.put("ft/s", (float) 3.2808);

fromMeter.put("ft/min", (float) 196.850);

fromMeter.put("ft/h", (float) 11811.02);

fromMeter.put("mps", (float) 0.0006213);

fromMeter.put("mpm", (float) 0.03728);

fromMeter.put("mph", (float) 2.236);

fromMeter.put("yd/s", (float) 1.0936);

fromMeter.put("yd/min", (float) 65.616);

fromMeter.put("yd/h", (float) 3937.0078);

Map<String,Float> toMeter = new HashMap<String,Float>();

toMeter.put("m/s", (float) 1);

toMeter.put("m/min", (float) 0.0166);

toMeter.put("m/h", (float) 0.000277);

toMeter.put("km/s", (float) 1000);

toMeter.put("km/min", (float) 16.66);

toMeter.put("km/h", (float) 0.277);

toMeter.put("ft/s", (float) 0.3048);

toMeter.put("ft/min", (float) 0.00508);

toMeter.put("ft/h", (float) 0.00008466);

toMeter.put("mps", (float) 1609.344);

toMeter.put("mpm", (float) 26.8224);

toMeter.put("mph", (float) 0.44704);

toMeter.put("yd/s", (float) 0.9144);

toMeter.put("yd/min", (float) 0.01524);

toMeter.put("yd/h", (float) 0.000254);

try

{

float a = toMeter.get(unit_from);

float b = fromMeter.get(unit_to);

rezultat = value * a * b;

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaForta(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromDyna = new HashMap<String,Float>();

fromDyna.put("Dyna(dyn)", (float) 1);

fromDyna.put("Kg-Forta(kgf)", (float)(0.00000509858));

fromDyna.put("Kilopond(kp)", (float) 0.000005098581);

fromDyna.put("Livre-Forta(lbf)", (float) 0.000011240447);

fromDyna.put("Newtons(N)", (float) 0.00005);

Map<String,Float> toDyna = new HashMap<String,Float>();

toDyna.put("Dyna(dyn)", (float) 1);

toDyna.put("Kg-Forta(kgf)", (float) 4903325);

toDyna.put("Kilopond(kp)", (float) 4903325);

toDyna.put("Livre-Forta(lbf)", (float) 2224110.807627);

toDyna.put("Newtons(N)", (float) 500000);

try

{

float a = toDyna.get(unit_from);

float b = fromDyna.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaMasa(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromGram = new HashMap<String,Float>();

fromGram.put("Miligrame(mg)", (float) 1000);

fromGram.put("Grame(g)", (float) 1);

fromGram.put("Kilograme(kg)", (float) 0.001);

fromGram.put("Funte(lb)", (float) 0.002204622);

fromGram.put("Uncii(oz-AV)", (float) 0.03527396);

fromGram.put("Slug", (float) 0.0000685217);

fromGram.put("Tone(t)", (float) 0.000001);

Map<String,Float> toGram = new HashMap<String,Float>();

toGram.put("Miligrame(mg)", (float) 0.001);

toGram.put("Grame(g)", (float) 1);

toGram.put("Kilograme(kg)", (float) 1000);

toGram.put("Funte(lb)", (float) 453.59237);

toGram.put("Uncii(oz-AV)", (float) 28.349523125);

toGram.put("Slug", (float) 14593.9029372);

toGram.put("Tone(t)", (float) 1000000);

try

{

float a = toGram.get(unit_from);

float b = fromGram.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaTemperatura(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromCelsius = new HashMap<String,Float>();

fromCelsius.put("Celsius – C", (float) 1);

fromCelsius.put("Fahrenheit – F", (float)33.8);

fromCelsius.put("Kelvin – K", (float) 274.15);

fromCelsius.put("Rankine – R", (float) 493.47);

Map<String,Float> toCelsius = new HashMap<String,Float>();

toCelsius.put("Celsius – C", (float) 1);

toCelsius.put("Fahrenheit – F", (float) -17.2222);

toCelsius.put("Kelvin – K", (float) -272.15);

toCelsius.put("Rankine – R", (float) -272.5944);

try

{

float a = toCelsius.get(unit_from);

float b = fromCelsius.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaArie(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromAri = new HashMap<String,Float>();

fromAri.put("Ari(a)", (float) 1);

fromAri.put("Acri(ac)", (float) 0.0247105381);

fromAri.put("Centimetrii(cm²)", (float) 1000000);

fromAri.put("Hectare(h)", (float) 0.01);

fromAri.put("Kilometri(km²)", (float) 0.0001);

fromAri.put("Metri(m²)", (float) 100);

fromAri.put("Yarzi(yd²)", (float) 119.5990046);

fromAri.put("Picioare(ft²)", (float) 1076.39104);

Map<String,Float> toAri = new HashMap<String,Float>();

toAri.put("Ari(a)", (float) 1);

toAri.put("Acri(ac)", (float) 40.468564224);

toAri.put("Centimetrii(cm²)", (float) 0.000001);

toAri.put("Hectare(h)", (float) 100);

toAri.put("Kilometri(km²)", (float) 10000);

toAri.put("Metri(m²)", (float) 0.01);

toAri.put("Yarzi(yd²)", (float) 0.0083612736);

fromAri.put("Picioare(ft²)", (float) 0.0009290304);

try

{

float a = toAri.get(unit_from);

float b = fromAri.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaVolum(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromLitre = new HashMap<String,Float>();

fromLitre.put("Mililitri", (float) 1000);

fromLitre.put("Decilitri", (float) 10);

fromLitre.put("Centilitri", (float) 100);

fromLitre.put("Litri", (float) 1);

fromLitre.put("Decalitri", (float) 0.1);

fromLitre.put("Hectolitri", (float) 0.01);

fromLitre.put("Kilolitri", (float) 0.001);

fromLitre.put("Galon(UK)", (float) 0.21996924);

fromLitre.put("Galon(USA)", (float) 0.26417205);

Map<String,Float> toLitre = new HashMap<String,Float>();

toLitre.put("Mililitri", (float) 0.001);

toLitre.put("Decilitri", (float) 0.1);

toLitre.put("Centilitri", (float) 0.01);

toLitre.put("Litri", (float) 1);

toLitre.put("Decalitri", (float) 10);

toLitre.put("Hectolitri", (float) 100);

toLitre.put("Kilolitri", (float) 1000);

toLitre.put("Galon(UK)", (float) 4.54609);

toLitre.put("Galon(USA)", (float) 3.7854117);

try

{

float a = toLitre.get(unit_from);

float b = fromLitre.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

public float CalculeazaInfo(String unit_from,String unit_to,Float value)

{

float rezultat = 0;

Map<String,Float> fromMB = new HashMap<String,Float>();

fromMB.put("Biti", (float) 8388608);

fromMB.put("Bytes", (float) 1048576);

fromMB.put("KiloBytes", (float) 1024);

fromMB.put("MegaBytes", (float) 1);

fromMB.put("GigaBytes", (float) 0.0009765625);

fromMB.put("TerraBytes", (float) ((float) 9.536743164063 * Math.pow(10,-7)));

Map<String,Float> toMB = new HashMap<String,Float>();

toMB.put("Biti", (float) ((float) 1.192092895508 * Math.pow(10,-7)));

toMB.put("Bytes", (float) ((float) 9.536743164062 * Math.pow(10,-7)));

toMB.put("KiloBytes", (float) 0.0009765625);

toMB.put("MegaBytes", (float) 1);

toMB.put("GigaBytes", (float) 1024);

toMB.put("TerraBytes", (float) 1048576);

try

{

float a = toMB.get(unit_from);

float b = fromMB.get(unit_to);

rezultat = (value * a * b);

}

catch(Exception ex)

{

}

return rezultat;

}

}

Clasa SQLiteAdapter:

public class SQLiteAdapter {

public static final String MYDATABASE_NAME = "Convertor";

private static final String Tabel_Conversie = "tblConversie";

public static final int MYDATABASE_VERSION = 1;

public static final String KEY_ID_conversie = "id_converse";

public static final String KEY_categorie = "categorie";

public static final String KEY_unitFrom = "conversie_din";

public static final String KEY_unitTo= "conversie_in";

public static final String KEY_Value = "valoare";

public static final String KEY_rezultat_conversie = "rezultat_conversie";

private static final String CREATE_Table_Conversie = "create table if not exists tblConversie(id_conversie integer primary key autoincrement ,"

+ "categorie text not null,conversie_din text not null,conversie_in text not null,valoare text not null,rezultat_conversie text not null);";

private SQLiteHelper sqLiteHelper;

private SQLiteDatabase sqLiteDatabase;

private Context context;

public SQLiteAdapter(Context c) {

context = c;

}

public SQLiteAdapter openToRead() throws android.database.SQLException {

sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,

MYDATABASE_VERSION);

sqLiteDatabase = sqLiteHelper.getReadableDatabase();

return this;

}

public SQLiteAdapter openToWrite() throws android.database.SQLException {

sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,

MYDATABASE_VERSION);

sqLiteDatabase = sqLiteHelper.getWritableDatabase();

return this;

}

public long SaveConversion(String categorie,String from,String to,String value,String rezultat)

{

long ret = 0;

ContentValues contentValues = new ContentValues();

contentValues.put(KEY_categorie, categorie);

contentValues.put(KEY_unitFrom, from);

contentValues.put(KEY_unitTo, to);

contentValues.put(KEY_Value, value);

contentValues.put(KEY_rezultat_conversie, rezultat);

try {

ret = sqLiteDatabase.insert(Tabel_Conversie, null,

contentValues);

} catch (SQLException e) {

e.printStackTrace();

ret = 0;

}

return ret;

}

public String GetAllConversions()

{

String rezultat_conversii = "";

String[] columns = new String[] { KEY_Value, KEY_unitFrom, KEY_rezultat_conversie, KEY_unitTo };

Cursor cursor = sqLiteDatabase.query(Tabel_Conversie, columns,

null, null, null, null, null);

for (cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()) {

for (int i = 0; i < columns.length; i++) {

rezultat_conversii = rezultat_conversii + cursor.getString(i) + ";";

}

rezultat_conversii += "~";

}

return rezultat_conversii;

}

public void close() {

sqLiteHelper.close();

}

//region SQLiteHelper Class

public class SQLiteHelper extends SQLiteOpenHelper {

public SQLiteHelper(Context context, String name,

CursorFactory factory, int version) {

super(context, name, factory, version);

}

@Override

public void onCreate(SQLiteDatabase db) {

// TODO Auto-generated method stub

db.execSQL(CREATE_Table_Conversie);

}

@Override

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

// TODO Auto-generated method stub

}

}

//endregion

}

Clasa fragment_arie

public class fragment_arie extends Fragment{

Utilities ut = new Utilities();

static String from,to,valoare,rezultat_conv;

@Override

public View onCreateView(LayoutInflater inflater,

ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(

R.layout.fragment_fr, container, false);

final Spinner s = (Spinner) view.findViewById(R.id.spinner_from);

final Spinner s1 = (Spinner) view.findViewById(R.id.spinnerTo);

final EditText value = (EditText)view.findViewById(R.id.editTextValue);

final TextView rezultat_conversie = (TextView) view.findViewById(R.id.rezultat);

// Inflate the layout for this fragment

ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_spinner_item, Utilities.valori_arie);

dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

//ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(getActivity().getBaseContext(), R.array.spinnerItems, android.R.layout.simple_spinner_item);

s.setAdapter(dataAdapter);

s1.setAdapter(dataAdapter);

s.setOnItemSelectedListener(new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<?> parent, View view,

int position, long id) {

from = s.getSelectedItem().toString();

try

{

float valuee = Float.valueOf(value.getText().toString());

float rezultat = ut.CalculeazaArie(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

}

catch(Exception ex)

{

rezultat_conversie.setText("");

}

}

@Override

public void onNothingSelected(AdapterView<?> parent) { }

});

s1.setOnItemSelectedListener(new OnItemSelectedListener() {

@Override

public void onItemSelected(AdapterView<?> parent, View view,

int position, long id) {

to = s1.getSelectedItem().toString();

try

{

float valuee = Float.valueOf(value.getText().toString());

float rezultat = ut.CalculeazaArie(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

}

catch(Exception ex)

{

rezultat_conversie.setText("");

}

}

@Override

public void onNothingSelected(AdapterView<?> parent) { }

});

value.addTextChangedListener(new TextWatcher(){

@Override

public void beforeTextChanged(CharSequence s, int start, int count,

int after) {}

@Override

public void onTextChanged(CharSequence s, int start, int before,

int count) {}

@Override

public void afterTextChanged(Editable s) {

try

{

valoare = value.getText().toString();

float valuee = Float.valueOf(value.getText().toString());

float rezultat = ut.CalculeazaArie(from, to, valuee);

rezultat_conversie.setText(String.format("%.3f", rezultat));

rezultat_conv = String.format("%.3f", rezultat);

}

catch(Exception ex)

{

rezultat_conversie.setText("");

}

}

});

return view;

}

}

Toate celelalte clase de tip fragment au aproximativ aceeasi structură. Ceea ce diferă este porțiunea de cod în care sunt încarcate elementele în spiner, lucru explicat în Capitolul 4, subcapitolul 4.3 .

Clasa fragment_conversii:

public class fragment_conversii extends Fragment{

private static SQLiteAdapter mySQLiteAdapter;

private LinearLayout mLinearListView;

private ArrayList<String> lista;

@Override

public View onCreateView(LayoutInflater inflater,

ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(

R.layout.show_conversii, container, false);

mySQLiteAdapter = new SQLiteAdapter(getActivity());

mySQLiteAdapter.openToRead();

mLinearListView = (LinearLayout) view.findViewById(R.id.linear_listview);

IncarcaLista();

return view;

}

private void IncarcaLista() {

try

{

String x= mySQLiteAdapter.GetAllConversions();

String[] listParts = null;

listParts = x.split("~");

lista = new ArrayList<String>();

for(int j = 0; j< listParts.length;j++)

{

lista.add(listParts[j]);

}

for (int i = 0; i < lista.size(); i++) {

LayoutInflater inflater = null;

inflater = (LayoutInflater) getActivity().getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View mLinearView = inflater.inflate(R.layout.conversii_row, null);

TextView valoare_din = (TextView) mLinearView.findViewById(R.id.txtFromValue);

TextView unitate_din = (TextView) mLinearView.findViewById(R.id.txtFromUnit);

TextView valoare_in = (TextView) mLinearView.findViewById(R.id.txtToValue);

TextView unitate_in = (TextView) mLinearView.findViewById(R.id.txtToUnit);

String disParts[] = null;

disParts = lista.get(i).toString().split(";");

valoare_din.setText(disParts[0].toString());

unitate_din.setText(disParts[1].toString());

valoare_in.setText(disParts[2].toString());

unitate_in.setText(disParts[3].toString());

mLinearListView.addView(mLinearView);

}

}

catch(Exception e)

{

e.printStackTrace();

}

}

}

Layout-ul fragment_fr:

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

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical"

android:background="@drawable/background">

<TextView

android:id="@+id/textViewValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignLeft="@+id/textViewFrom"

android:layout_alignParentTop="true"

android:layout_marginTop="130dp"

android:text="Value:"

android:textAppearance="?android:attr/textAppearanceMedium" />

<EditText

android:id="@+id/editTextValue"

android:layout_width="160dp"

android:layout_height="wrap_content"

android:layout_alignBaseline="@+id/textViewValue"

android:layout_marginLeft="35dp"

android:layout_toRightOf="@+id/textViewValue"

android:ems="10"

android:inputType="number" >

<requestFocus />

</EditText>

<TextView

android:id="@+id/textViewFrom"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_marginLeft="50dp"

android:layout_marginTop="200dp"

android:text="From :"

android:textAppearance="?android:attr/textAppearanceMedium" />

<Spinner

android:id="@+id/spinner_from"

android:layout_width="150dp"

android:layout_height="wrap_content"

android:layout_marginTop="200dp"

android:layout_marginLeft="40dp"

android:layout_toRightOf="@+id/textViewFrom" />

<TextView

android:id="@+id/TextViewTo"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentLeft="true"

android:layout_below="@+id/spinner_from"

android:layout_marginLeft="50dp"

android:layout_marginTop="20dp"

android:text="To: "

android:textAppearance="?android:attr/textAppearanceMedium" />

<Spinner

android:id="@+id/spinnerTo"

android:layout_width="150dp"

android:layout_height="wrap_content"

android:layout_marginTop="260dp"

android:layout_marginLeft="50dp"

android:layout_toRightOf="@+id/TextViewTo" />

<TextView

android:id="@+id/rezultat"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/spinnerTo"

android:layout_centerHorizontal="true"

android:layout_marginTop="80dp"

android:textAppearance="?android:attr/textAppearanceLarge" />

</RelativeLayout>

Layout-ul show_conversii:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context=".ShowDiscipline"

android:background="@drawable/back" >

<TextView

android:id="@+id/txtTittle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_marginTop="5dp"

android:layout_centerHorizontal="true"

android:text="Conversii salvate"

android:textColor="#000000"

android:textSize="25sp"

android:textAppearance="?android:attr/textAppearanceLarge" />

<ScrollView

android:id="@+id/scrollview"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_below="@+id/txtTittle"

android:layout_marginTop="15dp" >

<LinearLayout

android:id="@+id/linear_scroll"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical" >

<LinearLayout

android:id="@+id/linear_listview"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:layout_marginTop="15dp" />

</LinearLayout>

</ScrollView>

</RelativeLayout>

Layout-ul conversii_row:

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="vertical"

android:padding="10dp"

android:scrollbarAlwaysDrawVerticalTrack="@bool/abc_action_bar_embed_tabs_pre_jb" >

<LinearLayout

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="horizontal"

android:padding="@dimen/abc_action_bar_subtitle_top_margin" >

<TextView

android:id="@+id/txtFromValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginLeft="10dp"

android:textSize="18sp"

android:textStyle="bold"

android:textColor="#000000"

android:text="1" />

<TextView

android:id="@+id/txtFromUnit"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="20sp"

android:layout_marginLeft="5dp"

android:textColor="#000000"

android:text="2" />

<TextView

android:id="@+id/txtequals"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="20sp"

android:layout_marginLeft="5dp"

android:textColor="#000000"

android:text=" = " />

<TextView

android:id="@+id/txtToValue"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_marginLeft="10dp"

android:textSize="18sp"

android:textStyle="bold"

android:textColor="#000000"

android:text="1" />

<TextView

android:id="@+id/txtToUnit"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:textSize="20sp"

android:layout_marginLeft="5dp"

android:textColor="#000000"

android:text="2" />

</LinearLayout>

<View

android:layout_width="match_parent"

android:layout_height="1dp"

android:layout_marginTop="10dp"

android:background="#FF0000" />

</LinearLayout>

Similar Posts