Tutorial Android (6) – Cum sa construiesti si sa afisezi o noua activitate, fereastra sau formular

5 comments - This post in english

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:

Schema exemplului Android

Schema exemplului Android

Pentru a atinge obiectivul propus, crearea si afisarea unei noi activitati, vom defini etapele solutiei:

  1. definim un widget pe display-ul activitatii principale; acesta va fi utilizat pentru a deschide noua activitate;
  2. definim noua activitate (Activity) si layout-ul ei; de asemenea, declaram activitatea in fisierul manifest al aplicatiei Android, AndroidManifest.xml;
  3. 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)

 1: <?xml version="1.0" encoding="utf-8"?>
 2: <resources>
 3:     <string name="hello">Hello World, MainActivity!</string>
 4:     <string name="app_name">Create and display a new Activity</string>
 5:     <string name="btnClick">Click me !</string>
 6: </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:

 

 

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:

Fereastra New Activity

Fereastra New Activity

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.

Fereastra New Android XML File

Fereastra New 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.


,


  1. #1 by Alin on October 19th, 2011

    felicitari pentru munca! Tutorialele sunt usoare si destul de scurte, astfel incat nu te plictisesc.

  2. #2 by Lidia on March 12th, 2013

    Va multumesc pentru tutoriale! Foarte bune pentru incepatori, bine structurate.

  3. #3 by Vlad on December 15th, 2013

    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?

    • #4 by Catalin on January 6th, 2014

      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.

(will not be published)