© 2012 - cefriel primi esempi di interfacce grafiche con android docente: gabriele lombardi...

31
© 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi [email protected]

Upload: maddalena-bucci

Post on 01-May-2015

222 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

© 2012 - CEFRIEL

Primi esempi di interfacce grafiche con Android

Docente: Gabriele [email protected]

Page 2: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

© 2012 - CEFRIEL

The present original document was produced by CEFRIEL and the Teacher for the benefit and internal use of this course, and nobody else may claim any right or paternity on it. No right to use the document for any purpose other than the Intended purpose and no right to distribute, disclose, release, furnish or disseminate it or a part of it in any way or form to anyone without the prior express written consent of CEFRIEL and the Teacher.© copyright Cefriel and the Teacher-Milan-Italy-23/06/2008. All rights reserved in accordance with rule of law and international agreements.

Page 3: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

© 2012 - CEFRIEL

SommarioSommario

SLIDE CONTENUTO

MVC pattern Perché preoccuparsene, come implementarlo

Interagire con l’utente

Esempi di eventi e accesso ai dati della UI

Tutto in XML Come descrivere interfacce grafiche in XML: basi

Logging & Debugging Loggare per sapere, debuggare le proprie app

Widget e container Esempi di utilizzo di widget e container in XML

Page 4: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

I design pattern (GRASP, GoF, altri)

Cosa sono i design pattern?– Soluzioni efficaci a problemi frequenti;– le trovate «preconfezionate» in libri (GoF), su forum;– operano a diversi livelli (classe, collaborazione, framework,

componenti). GRASP:

– sono più linee guida che design pattern;– low copuling & high coesion sono i più importanti.

GoF:– dal libro «Design patterns» della gang of four;– si dividono in strutturali, creazionali, comportamentali;– descrivono soluzioni a livello di collaborazione.

MVC (Model View Control), MVP (Model View Presenter):

– definiscono una architettura astratta in vengono separati:• il modello dei dati su cui l’applicazione opera;• la/le viste dei dati da mostrare all’utente;• le operazioni da svolgere in risposta agli eventi.

– Non comprende la logica di business!!!© 2012 - CEFRIEL

Page 5: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

MVC e MVP

A programmare seguendo l’istinto:– si finisce per ottenere l’anti-pattern SmartGUI;– l’applicazione cresce attorno all’interfaccia grafica;– alla fine non saremo più in grado di staccare le

funzionalità dall’interfaccia (se non con molto sforzo).

Model e logica di business:– l’applicazione dovrebbe nascere sulla carta in UML;– il modello concettuale (dei dati) dovrebbe guidarci;

– ("Model Driven Design", Evans)

– la logica di business dovrebbe venir realizzata PRIMA dell’interfaccia di interazione con l’utente;

– realizzare sia una GUI che una CLI aiuta a separare. MVC e MVP vengono dopo:

– sono pattern da applicare quando il core esiste già;– servono per costruire l’interfaccia (grafica);

© 2012 - CEFRIEL

Page 6: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

MVC e MVP

MVC:– il modello rappresenta i

dati, eventualmente da DB;– le viste mostrano dati e

strumenti di interazione;– i controller interagiscono

con le viste e i dati per richiamare la logica di business.

MVP (view attiva/passiva):– riguarda la presentazione

dei dati (non l’interazione);– arricchisce l’interazione tra

modello e vista;– il presenter manipola i dati

perché possano essere presentati correttamente;© 2012 - CEFRIEL

Model DB

ControllerView

Logica di business

Model

View

Presenter

Page 7: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

MVC in Android

© 2012 - CEFRIEL

JavaBeans

DB

Contengono dati accessibili come property (vedi

dopo)

android.view.View

Meglio se generata da file

XML in /res/layout

Activity

Controller

ViewModel

Page 8: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Un primo esempio con layout in XML

Scopo:– realizzare una semplice calcolatrice che effettui i

calcoli su espressioni contenenti solo interi relativi e frazioni, esprimendo il risultato come una frazione.

Architettura:– decidiamo di dividere in due parti il «progetto»:

• libreria core di calcolo (in grado di parsare una stringa, ed effettuare i calcoli);

•applicazione Android con una semplice interfaccia classica da calcolatrice.

– L’interfaccia comprenderà:

•un layout XML in cui vengono descritti i widget da includere nell’interfaccia;

•un’attività che esegue le azioni richieste dagli eventi (aggiungere caratteri, fare conti).

© 2012 - CEFRIEL

Page 9: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Un layout da calcolatrice

© 2012 - CEFRIEL

<?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"> <EditText android:id="@+id/display" android:text="0" android:textColor="#000000" android:maxLines="5" android:enabled="false" android:editable="false" android:layout_width="fill_parent" android:layout_height="wrap_content"/> <TableLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:stretchColumns="0,1,2,3"> <TableRow> <Button android:id="@+id/canc" android:text="&lt;="/> <Button android:id="@+id/clear" android:text="C"/> <Button android:id="@+id/compute" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_span="2" android:text="="/> </TableRow> </TableLayout></LinearLayout>

Page 10: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Ascoltare gli eventi

© 2012 - CEFRIEL

@Override public void onCreate(Bundle savedInstanceState) { // Initialization: super.onCreate(savedInstanceState); setContentView(R.layout.main); // Connecting the event listeners: ((Button)findViewById(R.id.compute)).setOnClickListener(onCompute); ((Button)findViewById(R.id.num_0)).setOnClickListener(onAddChar);

… ((Button)findViewById(R.id.par_close)).setOnClickListener(onAddChar); ((Button)findViewById(R.id.canc)).setOnClickListener(onCanc); ((Button)findViewById(R.id.clear)).setOnClickListener(onClear); }

Scelgo il layout XML da utilizzare in questa

attività

Connetto gli eventi utilizzando dei miei

listener (vedere dopo)

Si osservi come vengono reperiti i widget dalla vista

Page 11: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Un ascoltatore

© 2012 - CEFRIEL

private OnClickListener onCompute = new OnClickListener() { public void onClick(View button) { try { // No errors up to now: ((EditText)findViewById(R.id.display)).setTextColor(Color.BLACK); // Obtaining the expression: CharSequence expr = ((EditText)findViewById(R.id.display)).getText(); // Computing: Fraction res = Calculator.compute(new StringBuilder(expr).toString()); // Setting the text result: ((EditText)findViewById(R.id.display)).setText(res.toString()); isInitial = true; // Done: } catch (Throwable t) { ((EditText)findViewById(R.id.display)).setTextColor(Color.RED); } } };

Se non ci sono errori il testo è

nero

Se ci sono errori il testo è rosso

Page 12: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Proviamola

Provate a compilare ed installare (nell’emulatore o anche nel dispositivo reale);– su emulatore provate il debuger;– osservate cosa avviene sulla vista.

Esercizio:– provate a modificare gli attributi

dei widgetper vedere che effetto hanno.

Esercizio:– aggiungete una checkbox con cui

decidere se mostrare il risultato come frazione o decimale;

– per farlo dovete utilizzare:

• il widget CheckBox;•OnCheckedChangeListener

© 2012 - CEFRIEL

Per la soluzione vedere in FractionCalc2

Page 13: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

A grande successo.. nuova release!

Associare un’icona all’app:– creare l’icona a risoluzioni diverse:

• in res/drawable 48x48• in res/drawable-ldpi 36x36• in res/drawable-hdpi 72x72

– modificare AndroidManifest.xml:– <application android:label="@string/app_name" – android:icon="@drawable/fraction_calc_icon">

– NOTA: nei nomi di risorse solo [a-z], [0-9], ‘_’ o ‘.’. Modificare versione mostrata ed effettiva (codice):

– modificare AndroidManifest.xml:– <manifest … package="com.gab.tests.android.fractioncalc"– android:versionCode="2" android:versionName="1.1">

– 1.1 verrà mostrato (nel market), 2 è un intero incrementale

© 2012 - CEFRIEL

Page 14: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Ho i tasti sul telefono.. Perché non usarli? Ogni attività può ricevere tanti eventi!

– Il tocco dello schermo viene usato di frequente…– …ma se ci sono tasti VERI vengono usati volentieri!

© 2012 - CEFRIEL

@Override public boolean onKeyUp(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_0:

onAddChar.onClick(findViewById(R.id.num_0)); break; case KeyEvent.KEYCODE_9:

onAddChar.onClick(findViewById(R.id.num_9)); break; case KeyEvent.KEYCODE_PLUS:

onAddChar.onClick(findViewById(R.id.op_PLUS)); break; case KeyEvent.KEYCODE_EQUALS:

onCompute.onClick(findViewById(R.id.compute)); break; case KeyEvent.KEYCODE_BACK:

onCanc.onClick(findViewById(R.id.canc)); break; default: return super.onKeyUp(keyCode, event); } return true; }

Page 15: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Inseriamo un’icona sul pulsante <=

Soluzione 1:– su ogni widget possiamo definire la proprietà

«background» con una risorsa «drawable»;– <Button android:id="@+id/canc"– android:layout_width="fill_parent"– android:layout_height="fill_parent"–

android:background="@android:drawable/ic_input_delete"/>

– NOTA: invece che riferirci a un drawable “nostro” ci siamo riferiti a uno predefinito:

•@android:drawable/ic_input_delete•per un elenco si vedano nell’SDK:

– android-sdk\platforms\android-10\data\res\drawable-ldpi– android-sdk\platforms\android-10\data\res\drawable-hdpi

Problemi con questa soluzione:– immagine adattata alle dimensioni del pulsante

(provate);– noi vorremmo sovrapporre l’icona sul pulsante.

© 2012 - CEFRIEL

Page 16: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Inseriamo un’icona sul pulsante <= Soluzione 2:

– al posto del pulsante inseriamo un layout relativo;– all’interno del layout inseriamo:

•il pulsante (riempiendo tutto lo spazio);•l’immagine (centrata ma non adattata).

– Ne risulta:

© 2012 - CEFRIEL

<RelativeLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:id="@+id/canc" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@android:drawable/ic_input_delete" android:layout_centerInParent="true"/></RelativeLayout>

Soluzione 3:– utilizzare un ImageButton (con src il drawable).

Page 17: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Ruotare il dispositivo e…

…il layout non va più bene!– (nell’emulatore provare con

CTRL+F12 (sinistro) Per orientazioni diverse:

– non serve cambiare controller;– servono view differenti.

Creiamo la cartella per i layout XML in versione landscape:– res/layout-land

Creiamoci dentro un layoutalternativo per il landscape:– tabella 5x4

Giochiamo con l’orientazione© 2012 - CEFRIEL

Page 18: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Layout alternativo

Altri strumenti esistono per livelli di API più alti:– dalle API14 esiste il GridLayout:

– vedi in altriEsempi/xml/main_conGrid.xml

– occhio al range di dispositivi che volete supportare; L’esempio con GridLayout:

© 2012 - CEFRIEL

<GridLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:columnCount="5" android:rowCount="4">

… <Button android:id="@+id/compute" android:layout_rowSpan="2" android:layout_gravity="fill" android:text="="/>

… </GridLayout>

Essendo noti sfruttiamo numero

righe/colonne

Usiamo rowSpan per riempire 2 righe,

gravity fill per allargare il Button

Page 19: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Se sappiamo cos’è successo.. diciamolo!

Mostriamo una dialog di errore:– se c’è una divisione per zero;– negli altri casi (problema di sintassi);

Più modi per mostrare una dialog:– utilizzando l’XML per descriverne

una, ed eseguendo showDialog;– istanziandola ed invocando show;– con DialogFragment.

Il primo è deprecato (non usare); Vediamo il secondo:

© 2012 - CEFRIEL

final AlertDialog dialog = new AlertDialog.Builder(this).create();dialog.setButton("Chiudi", new android.content.DialogInterface.OnClickListener() { public void onClick(DialogInterface dlgInt, int button) { dialog.hide(); } });dialog.setTitle(title);dialog.setMessage(message);dialog.show();

Page 20: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Logging per sapere cosa succede

Come loggare:– da specificare le seguenti informazioni:

– livello del log (verbose, debug, info, warning, error, wtf(!!!)…);

– CHI genera il log (classe? Package? Stringa a scelta);– COSA è successo (messaggio di log).

– utilizzare la classe Log (metodi statici):

•se bastano i metodi v, d, i, w, e, wtf;•println è il metodo «raw» per scrivere log;

Come loggare in maniera furba:– la generazione di log è fastidiosa e onerosa;– centralizzandola la si può controllare!– si veda la classe Logger in FractionCalc2.– Il compilatore e l’ottimizzatore SANNO il fatto loro!

E per leggere i log? – adb logcat FractionCalc:i *:s (filtrato, livelli

[v,d,i,w,e,f,s]) © 2012 - CEFRIEL

Page 21: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Logging: cosa succede?

© 2012 - CEFRIEL

Page 22: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Debugging: step-by-step, monitor

Per poter eseguire il debug su dispositivo:– abilitarlo sul dispositivo da

impostazioniapplicazioni– abilitarlo nell’applicazione (attributo del manifest):

– <application android:label="@string/app_name" – android:icon="@drawable/fraction_calc_icon"– android:debuggable="true">

– in NetBeans, build e debug: per l’emulatore

– se non abbiamo ancora provato… è l’ora di farlo!

per il dispositivo fisico– richiede la presenza del dispositivo, ma volte è più rapido.

Un monitor con cui accedere al device:– nell’sdk (dir tools, deve essere nel path) troviamo:

•DDMS (Dalvik Debug Monitor Service)…•…proviamo a lanciarlo dalla linea di

comando! © 2012 - CEFRIEL

Page 23: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

DDMS DDMS comunica col device

tramite:– servizio demone adb-server;– TCP/IP con forward su USB

DDMS permette di eseguire:– monitoring di ram, processi, thread,

allocazione, gc, radio, gps, …;– cattura di screen-shot;– interazione con il FS.

© 2012 - CEFRIEL

Page 24: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Debug delle interfacce grafiche Analizzare l’albero delle view:

– ci viene fornito lo strumento hierarchyviewer:

•cattura un’istantanea dello stato dell’albero;•ci permette di vedere:

© 2012 - CEFRIEL

• come è strutturato l’albero delle view;

• per ogni nodo: posizione e dimensioni;

• uno sketch dell’interfaccia grafica;

• lo screen-shot nodo per nodo;

• Immagine del tutto.

Page 25: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Testing Lo unit testing serve a testare in automatico e

ripetibilmente la propria applicazione:– simulare dei casi d’uso dell’applicazione (scimmia);– testare una porzione di applicazione (componenti).

Facciamo correre la scimmia:– in modalità pseudo-random:

– adb shell monkey -p com.gab.tests.android.fractioncalc 1000– ammaestrandone una col pitone:

– comando monkeyrunner per eseguire uno script python;– un esempio di seguito, ma si può fare di tutto:

© 2012 - CEFRIEL

from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice

device = MonkeyRunner.waitForConnection()

package = 'com.gab.tests.android.fractioncalc'activity = package + '.FractionCalc'device.startActivity(component=package + '/' + activity)

device.touch(50,200,MonkeyDevice.DOWN_AND_UP) # 1device.touch(50,300,MonkeyDevice.DOWN_AND_UP) # 7…

Ottengo il device

Avvio l’applicazione

Simulazione tocco

Page 26: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Come funziona l’Android Unit Testing

© 2012 - CEFRIEL

Nostra applicazione in

esecuzioneTools per

accedere agli internals

Pacchetti di test che usano gli

strumenti

Page 27: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Unit Testing

Creazione di un progetto di test:– utilizziamo questa volta i tool da riga di comando:

•dalla directory radice del progetto da testare:

– android create test-project -m ../../FractionCalc2 -n FractionCalc2Test -p tests

– viene generata una dir tests con un progetto di testing:

•vengono creati per noi (tra il resto):– AndoridManifest.xml vediamo cosa contiene– FractionCalcTest.java vediamo cosa contiene

Esecuzione dei test:– prima di poter eseguire con successo dei test:

•dobbiamo strumentare i test…;•… e scrivere le unità di testing automatico.

– per strumentare ed eseguire i nostri test:

•ant/bin deve essere nel PATH© 2012 - CEFRIEL

Page 28: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Unit Testing

Preparare ed eseguire i test:– dobbiamo prima strumentare l’applicazione di test:

– ant instrument install

– poi possiamo eseguire una prima prova:– adb shell am instrument -w -e class

com.gab.tests.android.fractioncalc.FractionCalcTest com.gab.tests.android.fractioncalc.tests/android.test.InstrumentationTestRunner

•NOTA: fallisce perché non ci sono unità. Unità di testing:

– Android testing framework estende JUnit;– esistono unità di test (foglie) e suite di test (rami);– è possibile definire una vera e propria foresta di test;– ogni unità di test comprende più test più le fixtures.

© 2012 - CEFRIEL

Page 29: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Preparare le unità di test

Ci è stata preparata la classe FractionCalcTest:– implementato per Android, eredita da JUnit:

– ActivityInstrumentationTestCase2<FractionCalc> ActivityTestCase InstrumentationTestCase TestCase

– si prepara per lavorare con la nostra attività main:– public FractionCalcTest() {

super("com.gab.tests.android.fractioncalc", FractionCalc.class); }

– dobbiamo aggiungere i test e ciò che ci sta attorno:

© 2012 - CEFRIEL

Activity frac;public void setUp() { frac = getActivity(); }public void tearDown() { frac.finish(); } public void testExample() { sendKeys("1 7 SLASH 2 MINUS 2 SLASH 4 EQUALS");

CharSequence text = ((EditText)frac.findViewById(R.id.display)).getText(); assertEquals("Result of 17/2-2/4=", "8", new StringBuilder(text).toString());}

Page 30: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

L’esecuzione dei test

Vanno installati ogni volta:– ant instrument install– ant test

– …– -test-project-check:

– test:– [echo] Running tests ...– [exec]– [exec]

com.gab.tests.android.fractioncalc.FractionCalcTest:.– [exec] Test results for InstrumentationTestRunner=.– [exec] Time: 3.263– [exec]– [exec] OK (1 test)– [exec]– [exec]

– BUILD SUCCESSFUL– Total time: 8 seconds

Provate ad osservare l’emulatore durante il test!!! © 2012 - CEFRIEL

Page 31: © 2012 - CEFRIEL Primi esempi di interfacce grafiche con Android Docente: Gabriele Lombardi lombardi@dsi.unimi.it

Da qui dove si va?

Cosa abbiamo visto sino ad ora?– Abbiamo «giocato» con una prima applicazione;– abbiamo costruito una GUI e ascoltato degli

eventi;– abbiamo provato ad estenderla (versione 2);– abbiamo scoperto come fare testing automatico e

debugging della nostra applicazione (strumenti). Cosa manca?

– Non abbiamo formalizzato COSA una attività sia;– non abbiamo esplorato l’universo dei widget;– in Android non esistono mica solo le GUI!!!

Continuiamo a giocare!

© 2012 - CEFRIEL