In acest articol vom sunt descrise elementele de baza necesare pentru dezvoltarea unei aplicatii mobile Android, care are mai multe ferestre sau activitati. Pentru a face acest lucru, trebuie sa stim cum sa construim si sa afiseze o noua fereastra (formular) sau activitate (pentru restul articolului ne rezumam la vocabularul Android si vom folosi termenul de activitate pentru a indica o fereastra sau formular).
Am vazut in articolele anterioare ale Tutorialului Android, care sunt fundamentele unei aplicatii Android si ale componentelor sale. De asemenea, am vazut ca in spatele unei ferestre exista o instanta de tip activitate care are un ciclu de viata si un display (o interfata cu utilizatorul).
Alte subiecte care fac parte din acest tutorial Android sunt accesibile prin intermediul articolului Tutorial Android – Descriere si cuprins.
Schita aplicatiei mobile Android dezvoltata in acest articol (proiectul Eclipse pentru acest exemplu, este disponibil la sfârsitul acestui articol) este:
Pentru a atinge obiectivul propus, crearea si afisarea unei noi activitati, vom defini etapele solutiei:
- definim un widget pe display-ul activitatii principale; acesta va fi utilizat pentru a deschide noua activitate;
- definim noua activitate (Activity) si layout-ul ei; de asemenea, declaram activitatea in fisierul manifest al aplicatiei Android, AndroidManifest.xml;
- definim in activitatea principala un eveniment si handler-ul sau, care va afisa noua activitate;
Solutia este construita pornind de la sablonul de proiect Android ce este generat de plugin-ul ADT pentru Eclipse. Proiectul are urmatoarele setari:
- Project Name (Nume proiect): AndroidSecondActivity
- Build target (Platforma): Android 2.3.3
- Application Name (Nume aplicatie): Create and display a new Activity
- Package name (Nume pachet): eu.itcsolutions.android.tutorial
- Create Activity (Activitate): MainActivity
- Min SDK Version (Versiune SDK): 10
Pasul 1. Interfata cu utilizatorul a activitatii principale va fi construita intr-o maniera declarativa (folosind fisiere XML de layout), deoarece vom folosi codJ ava pentru lucruri mai complexe. Pentru a deschide noua activitate, vom plasa un buton (Button) pe ecran. Atunci când utilizatorul il va selecta, noua activitate va fi afisata.
1.1. Editati fisierul /res/values/strings.xml
al proiectului si adaugati un element nou. Utilizati editorul text si nu editorul vizual pentru resurse (Resource View), deoarece in primul modificarile se fac mai rapid. Adaugati elementul nou dupa cele existente, pe linia 5 (hello este pentru TextView si app_name este pentru bara de titlu a activitatii principale)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello World, MainActivity!</string> <string name="app_name">Create and display a new Activity</string> <string name="btnClick">Click me !</string> </resources>
1.2. AAdauga pe ecran o instanta de tip Button prin editarea fisierului /res/layout/main.xml
din proiect. Aveti posibilitatea sa stergeti elementul TextView existent, care este folosit pentru a afisa mesajul dat de sirul de caractere hello. Proprietatile instantei de tip Button care sunt initializate:
- Text: sirul de caractere btnClick din fisierul strings.xml. Daca utilizati design-ul declarativ, atunci elementul este accesat cu ajutorul sintaxei “@string/btnClick“. Pentru abordarea procedurala, resursa de tip sir de caractere este accesata cu ajutorul getString(R.string.btnClick).
- Width: wrap_content care indica o dimensiune egala cu dimensiunea textului;
- Height: wrap_content
- Id: buttonClick. Daca utilizati abordarea declarativa, atunci ID-ul instantei Button este definit utilizând proprietatea android:id. Proprietatea este initializata cu o valoare ce are sintaxa “@+ id/id_name“. Proprietatea android:id este echivalentul referintei de tip Button atunci când scrieti cod Java si va fi folosita pentru a desemna acea instanta buton (amintiti-va ca atunci când utilizati proiectarea declarativa a interfetei nu scrieti cod Java, insa mai târziu, poate este nevoie sa accesati din cod butonul). Daca utilizati editorul vizual pentru a plasa butonul pe ecran, se va genera un ID implicit (android:id = “@+id/button1”) pentru instanta de tip Button. Daca nu utilizati editorul grafic, atunci adaugati proprietatea in descrierea elementului <Button>.
Fie ca utilizati editorul vizual pentru layout sau nu, fisierul main.xml trebuie sa arate ca acesta (am sters elementul TextView existent si am centrat continutul utilizand atributul android:gravity al elementului LinearLayout:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_vertical|center_horizontal" > <Button android:text="@string/btnClick" android:id="@+id/buttonClick" android:layout_width="wrap_content" android:layout_height="wrap_content"> </Button> </LinearLayout>
Pasul 2. Pentru a defini o noua activitate trebuie sa cream o noua clasa care extinde Activity si, de asemenea, un nou layout pentru ea. Pentru a face acest lucru avem doua posibilitati:
- sa avem o abrodare muncitoreasca si sa scriem totul de la zero
- sa utilizam editorul vizual pentru fisierul manifest (un editor WYSIWYG – What You See Is What You Get cu mai multe tab-uri in partea de jos, care este deschis in mod implicit când selectati fisierul manifest) care sa genereaza o parte din codul necesar (a se vedea Cum se defineste o clasa de tip Activity cu editorul vizual Android Manifest sau fara).
In acest exemplu voi folosi prima abordare. Pentru a deschide editor text pentru XML, selectati tab-ul ce contine numele fisierului manifest (ultimul tab) din editorul WYSIWYG.
2.1. Clasa este creata ca orice clasa Java, folosind File -> New -> Class. Numele ei este SecondActivity iar android.app.Activity este superclasa sa:
2.2. Deoarece plugin-ul ADT pentru Eclipse nu este de ajutor cand se construieste o noua activitate in aceasta maniera, trebuie sa editam clasa de la zero:
package eu.itcsolutions.android.tutorial; import android.app.Activity; import android.os.Bundle; public class SecondActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
2.3. Definim un layout pentru noua activitate. Pentru aceasta, Eclipse este oarecum de ajutor deoarece exista wizard-ul New Android XML File. Pentru a-l deschide , selectati proiectul si apoi folositi optiunea File -> New -> Other din meniul Eclipse. Din categoria Android selectati Android XML File.
Numiti noul fisier de layout, second.xml si editati-l prin adaugarea unui TextView. Textul controlului TextView este definit direct in fisierul de layout (NU este recomandat).
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="This is the second Activity" /> </LinearLayout>
2.4. Facem legatura intre fisierul de layout second.xml si activitatea SecondActivity prin apelul functiei setContentView() in metoda onCreate() a clasei:
this.setContentView(R.layout.second);
2.5. Important ! Declarati activitatea SecondActivity in fisierul manifest al proiectului Android, AndroidManifest.xml. Pentru a face acest lucru, puteti utiliza tabul Android Manifest Application sau puteti utiliza editorul text pentru XML (tabul AndroidManifest.xml). In acest exemplu vom folosi ultima optiunea si vom adauga urmatoarea linie in fisierul XML, intre <application> si </application> (dupa declaratia activitatii principale):
<activity android:name="SecondActivity" android:label="Second Activity"> </activity>
Pasul 3. Evenimentul care va afisa a doua activitate este generat atunci când utilizatorul face clic pe buton. Arhitectura event-handler este aceeasi ca in orice aplicatie Java JSE. Evenimentul este administrat de catre sistem si aplicatia defineste si inregistreaza handler-i pentru acel eveniment.
3.1. Controlul care ofera handler sau care reprezinta listener-ul pentru eveniment este butonul din activitatea principala. Pentru a-l inregistra ca listener trebuie sa referim instanta butonului din codul Java. Dar avem o problema, butonul a fost definit in fisierul XML pentru layout.
- Important !
- Pentru a obtine referinta unui element de tip View, definit in fisierul layout XML, aveti posibilitatea sa folositi metoda findViewById(int ID) din clasa View. Ca argument, se utilizeaza constanta statica ce este generata in clasa R. De asemenea, element XML trebuie sa aiba un atribut android:id cu o valoare de tipul “@+id/id_name“.
Dupa ce obtinem referinta butonului, printr-un apel al metodei findViewById(int ID), o vom inregistra ca listener folosind setOnCLickListener(). Acest lucru se face in metoda onCreate(), supradefinita in activitatea principala, dupa apelul functiei setContentView():
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //get the Button reference //Button is a subclass of View //buttonClick if from main.xml "@+id/buttonClick" View v = findViewById(R.id.buttonClick); //set event listener v.setOnClickListener(this); }
Dupa adaugarea codul anterior, veti primi o eroare de compilator. O vom rezolva imediat.
Dupa cum puteti vedea, metoda setOnCLickListener(OnCLickListener l) necesita o instanta a unei clase care implementeaza interfata OnClickListener, si care ofera astfel un handler pentru acest eveniment.
3.2. Pentru a defini un handler pentru evenimentul OnClick, vom implementa interfata android.view.View.OnClickListener. Interfata are o metoda abstracta, onClick(), ce trebuie fie supradefinita. Modificati clasa MainActivity prin adaugarea urmatoarei secvente:
//implement the OnClickListener interface public class MainActivity extends Activity implements OnClickListener { ... //overrides the OnClickListener interface method @Override public void onClick(View arg0) { } }
3.3. Parametrul metodei OnClick(View arg0) reprezinta referinta la widget-ul care a lansat evenimentul atunci când a fost selectat. Comparam aceasta referinta cu cea a butonului de pe interfata (avem un singur buton, dar este mai bine sa verifici).
3.4. Dupa cum va amintiti din articolul Concepte, activitati si resurse ale unei aplicatii Android, componenta de tip Intent reprezinta un mesaj asincron utilizat pentru a activa activitati. Deci, daca vrem sa afisam o noua activitate, trebuie sa utilizam o referinta de tip Intent. A doua activitate este afisata folosind metoda startActivity() a clasei Activity.
@Override public void onClick(View arg0) { if(arg0.getId() == R.id.buttonClick){ //define a new Intent for the second Activity Intent intent = new Intent(this,SecondActivity.class); //start the second Activity this.startActivity(intent); } }
Asta este tot. Rulati si testati aplicatia Android. Pentru a reveni la activitatea principala, folositi butonul return de pe tastatura emulatorului.
- Important !
- NU UITATI sa declarati SecondActivity in fisierul manifest. Fara a face acest lucru, veti primi un mesaj de eroare si o exceptie de tip ActivityNotFoundException.
Daca va ajuta, puteti verifica codul sursa al proiectului Android.
Alte subiecte care fac parte din acest tutorial Android sunt accesibile prin intermediul articolului Tutorial Android – Descriere si cuprins.
Daca ai probleme cu exemplele sau crezi ca nu ai inteles elementele descrise, pune o intrebare in zona de comentarii si iti vom raspunde imediat. De asemenea, orice sugestie sau obervatie care duce la imbunatatirea materialului este bine venita.
Daca ti-a placut sau ti-a fost util acest tutorial atunci spune-le si altora despre el sau arunca-ti o privire pe reclamele din aceasta pagina. Referirea acestui material este cel mai bun mod de a aprecia autorul.
felicitari pentru munca! Tutorialele sunt usoare si destul de scurte, astfel incat nu te plictisesc.
Va multumesc pentru tutoriale! Foarte bune pentru incepatori, bine structurate.
Si ca sa fac al doilea buton si sa-l leg de o noua activitate, cum fac? Adica, eu am construit 4 butoane in main.xml, si primul buton deschide o noua activitate, am facut la fel si pentru al doilea, insa cel de-al doilea, nu face nimic, nu deschide nimic.. ce ar trebui sa adaug?
Salut Vlad,
Pentru al 2-lea buton trebuie abonat acelasi listener la fel cum ai facut la pasul 3.1. Daca consideram ca al 2-lea buton se numeste buttonClick2 atunci in onCreate() adaugi
View v2 = findViewById(R.id.buttonClick2);
//set event listener
v2.setOnClickListener(this);
iar in metoda onClick testezi butonul care a fost apasat:
@Override
public void onClick(View arg0) {
if(arg0.getId() == R.id.buttonClick){
//define a new Intent for the second Activity
Intent intent = new Intent(this,SecondActivity.class);
//start the second Activity
this.startActivity(intent);
}
else
if(arg0.getId() == R.id.buttonClick2){
//actiuni pentru butonul 2
}
}
Mai exista o alta solutie, preferata de programatorii cu experienta insa aici lucrurile devin un pic complicate (o sa mai pun un articol pe tema asta). Se defineste o clasa interna anonima Java doar pentru a putea defini listener pentru fiecare butona. In realitatea asa se fac lucrurile insa eu nu am vrut sa complic lucrurile in acest articol. In realitate, implementarea interfetei OnClickListener in MainActivity nu este eficienta deoarece ai un listener pentru toate butoanele.