Android Studio per principianti, parte 2: esplora e codifica l'app

Aggiornato: gennaio 2020.

Nella parte 1 dell'introduzione di questo principiante ad Android Studio, hai configurato Android Studio nel tuo ambiente di sviluppo e hai imparato a conoscere l'interfaccia utente. Ora, nella parte 2, codificherai la tua prima app.

L'app mobile animata consiste in una singola attività, che presenta il personaggio del robot Android di Google e un pulsante per animare il personaggio. Facendo clic sul pulsante, il personaggio cambia gradualmente colore da verde a rosso a blu, quindi di nuovo a verde. Sebbene l'app non sia particolarmente utile, scriverla ti aiuterà a familiarizzare con l'utilizzo di Android Studio. Nella parte 3, creerai ed eseguirai l'app utilizzando un emulatore di dispositivo Android e un tablet Kindle Fire.

Si noti che questa serie è stata aggiornata per Android Studio 3.2.1, l'attuale versione stabile al momento della stesura di questo documento.

Progetto di Android Studio e finestre dell'editor

Ho introdotto la finestra principale di Android Studio alla fine della Parte 1. Questa finestra è divisa in diverse aree, inclusa una finestra Progetto in cui identifichi i file di risorse di un'app e varie finestre dell'editor in cui scriverai il codice e specificherai le risorse per le app mobili in Android Studio. La finestra del progetto e una finestra dell'editor sono mostrate nella Figura 1.

Jeff Friesen

La finestra Progetto evidenzia W2A , che è il nome del W2A.javafile sorgente dell'app (sebbene l' .javaestensione del file non sia mostrata). A W2A corrisponde una finestra dell'editor, raggiungibile facendo doppio clic su W2A nella finestra Progetto. La finestra dell'editor rivela il contenuto corrente del file, in questo caso il codice sorgente Java scheletrico per l'attività principale dell'app.

Ogni finestra dell'editor è associata a una scheda. Ad esempio, la finestra dell'editor di W2A è associata a una scheda W2A.java . Viene mostrata anche una seconda scheda identificata come main.xml (il layout basato su XML predefinito per l'attività principale dell'app). Si passa da una finestra dell'editor all'altra facendo clic sulla scheda della finestra.

scarica Ottieni il codice Scarica il codice sorgente per l'app di esempio per Android: W2A.java. Creato da Jeff Friesen per JavaWorld.

L'app di esempio per Android

L'app di esempio ( W2A.java ) consiste in un'attività principale che mostra il personaggio del robot Android e un pulsante. Quando l'utente preme il pulsante, il robot si anima attraverso una serie di colori. In questa sezione, esploreremo il codice sorgente e le risorse dell'attività.

Esplora e codifica l'app di esempio per Android

Il codice sorgente dell'attività è memorizzato nel file W2A.java, presentato nel Listato 1.

Listato 1. W2A.java

 package ca.javajeff.w2a; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.ImageView; public class W2A extends Activity { AnimationDrawable androidAnimation; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ImageView androidImage = (ImageView) findViewById(R.id.android); androidImage.setBackgroundResource(R.drawable.android_animate); androidAnimation = (AnimationDrawable) androidImage.getBackground(); final Button btnAnimate = (Button) findViewById(R.id.animate); View.OnClickListener ocl; ocl = new View.OnClickListener() { @Override public void onClick(View v) { androidAnimation.stop(); androidAnimation.start(); } }; btnAnimate.setOnClickListener(ocl); } } 

Il W2A.javafile inizia con un'istruzione package , che nomina package ( ca.javajeff.w2a) che memorizza la W2Aclasse. Questo è seguito da una serie di istruzioni di importazione per vari tipi di API Android. Successivamente, il codice descrive la W2Aclasse, che si estende android.app.Activity.

W2Aprima dichiara un androidAnimationcampo di istanza di tipo android.graphics.drawable.AnimationDrawable. Gli oggetti di tipo AnimationDrawabledescrivono animazioni fotogramma per fotogramma, in cui l'elemento disegnabile corrente viene sostituito con l'elemento disegnabile successivo nella sequenza di animazione.

Cos'è un disegnabile?

Un disegnabile è qualcosa che può essere disegnato, come un'immagine. AnimationDrawableestende indirettamente la android.graphics.drawable.Drawableclasse astratta , che è un'astrazione generale per un oggetto disegnabile.

Il metodo onCreate ()

Tutto il lavoro dell'app avviene nel metodo di W2Asovrascrittura di onCreate(Bundle): non sono necessari altri metodi, il che aiuta a mantenere l'app semplice.

onCreate(Bundle) prima invoca il suo stesso metodo della superclasse, una regola che deve essere seguita da tutti i metodi di attività che sovrascrivono.

Questo metodo viene quindi eseguito setContentView(R.layout.main)per stabilire l'interfaccia utente dell'app. R.layout.mainè un identificatore (ID) per una risorsa dell'applicazione, che risiede in un file separato. Interpreti questo ID come segue:

  • Rè il nome di una classe generata durante la creazione dell'app. Questa classe è denominata Rperché il suo contenuto identifica vari tipi di risorse dell'applicazione, inclusi layout, immagini, stringhe e colori.
  • layoutè il nome di una classe annidata all'interno R. Una risorsa dell'applicazione il cui ID è memorizzato in questa classe descrive una specifica risorsa di layout. Ogni tipo di risorsa dell'applicazione è associato a una classe nidificata denominata in modo simile. Ad esempio, stringidentifica le risorse di stringa.
  • mainè il nome di una intcostante in base dichiarata all'interno layout. Questo ID risorsa identifica la risorsa di layout principale. In particolare, si mainriferisce a un main.xmlfile che memorizza le informazioni sul layout dell'attività principale. mainè l W2A'unica risorsa di layout.

Passando R.layout.maina Activity's void setContentView(int layoutResID)metodo istruisce Android per creare una schermata dell'interfaccia utente utilizzando le informazioni memorizzate nel layout di main.xml. Dietro le quinte, Android crea i componenti dell'interfaccia utente descritti in main.xmle li posiziona sullo schermo del dispositivo come specificato dai main.xmldati di layout di.

La schermata si basa sulle visualizzazioni (astrazioni dei componenti dell'interfaccia utente) e sui gruppi di visualizzazioni (visualizzazioni che raggruppano i componenti dell'interfaccia utente correlati). Le viste sono istanze di classi che sottoclassano la android.view.Viewclasse e sono analoghe ai componenti AWT / Swing. I gruppi di viste sono istanze di classi che sottoclassano la android.view.ViewGroupclasse astratta e sono analoghi ai contenitori AWT / Swing. Android fa riferimento a visualizzazioni specifiche (come pulsanti o spinner) come widget .

Continuando, onCreate(Bundle)esegue ImageView androidImage = (ImageView) findViewById(R.id.android);. Questa istruzione chiama prima Viewil View findViewById(int id)metodo di per trovare l' android.widget.ImageViewelemento dichiarato in main.xmle identificato come android. Lo istanzia ImageViewe lo inizializza sui valori dichiarati nel main.xmlfile. L'istruzione salva quindi il riferimento di questo oggetto nella variabile locale androidImage.

ImageView e AnimationDrawable

Successivamente, l' androidImage.setBackgroundResource(R.drawable.android_animate);istruzione richiama il metodo ImageViewinherited (from View) void setBackgroundResource(int resID), impostando lo sfondo della vista sulla risorsa identificata da resID. Le R.drawable.android_animateidentifica argomento un file XML denominato android_animate.xml(presentata in seguito), che memorizza le informazioni sull'animazione, e che è memorizzato in res's drawablesottodirectory. Il setBackgroundResource()bando collega la androidImagevista alla sequenza di immagini descritta da android_animate.xml, che verrà disegnata su questa vista. L'immagine iniziale viene disegnata come risultato di questa chiamata al metodo.

ImageViewconsente a un'app di animare una sequenza di drawable chiamando i AnimationDrawablemetodi. Prima che l'app possa eseguire questa operazione, deve ottenere ImageViewi file AnimationDrawable. L' androidAnimation = (AnimationDrawable) androidImage.getBackground();istruzione di assegnazione che segue esegue questa operazione richiamando il metodo ImageViewinherited (from View) Drawable getBackground(). Questo metodo restituisce il AnimationDrawableper il dato ImageView, che viene successivamente assegnato al androidAnimationcampo. L' AnimationDrawableistanza viene utilizzata per avviare e interrompere un'animazione, un processo che descriverò tra breve.

Infine, onCreate(Bundle)crea il pulsante Animate . Richiama findByViewId(int)per ottenere le informazioni sul pulsante main.xml, quindi crea un'istanza della android.widget.Buttonclasse.

It then employs the View class's nested onClickListener interface to create a listener object. This object's void onClick(View v) method is invoked whenever the user clicks the button. The listener is registered with its Button object by calling View's void setOnClickListener(AdapterView.OnClickListener listener) method.

To stop, then start the animation, Animate's click listener invokes androidAnimation.stop(); followed by androidAnimation.start();. The stop() method is called before start() to ensure that a subsequent click of the Animate button causes a new animation to begin.

Update and save your code

Before we continue, replace the skeletal code in your W2A.java tab with the code from Listing 1. Save the contents of this window by pressing Ctrl+S, or select Save All from the File menu.

Coding the Android app's main.xml

The app's main activity is associated with an XML-based layout, which is stored in file main.xml, and which is presented in Listing 2.

Listing 2. main.xml

After the XML declaration, Listing 2 declares a LinearLayout element that specifies a layout (a view group that arranges contained views on an Android device's screen in some manner) for arranging contained widgets (including nested layouts) either horizontally or vertically across the screen.

The tag specifies several attributes for controlling this linear layout. These attributes include the following:

  • orientation identifies the linear layout as horizontal or vertical. Contained widgets are laid out horizontally or vertically, and the default orientation is horizontal. "horizontal" and "vertical" are the only legal values that can be assigned to this attribute.
  • layout_width identifies the width of the layout. Legal values include "fill_parent" (to be as wide as the parent) and "wrap_content" (to be wide enough to enclose content). (Note that fill_parent was renamed to match_parent in Android 2.2, but is still supported and widely used.)
  • layout_height identifies the height of the layout. Legal values include "fill_parent" (to be as tall as the parent) and "wrap_content" (to be tall enough to enclose content).
  • gravity identifies how the layout is positioned relative to the screen. For example, "center" specifies that the layout should be centered horizontally and vertically on the screen.
  • background identifies a background image, a gradient, or a solid color. For simplicity, I've hardcoded a hexadecimal color identifier to signify a solid white background (#ffffff). (Colors would normally be stored in colors.xml and referenced from this file.)

The LinearLayout element encapsulates ImageView and Button elements. Each of these elements specifies an id attribute, which identifies the element so that it can be referenced from code. The resource identifier (special syntax that begins with @) assigned to this attribute begins with the @+id prefix. For example, @+id/android identifies the ImageView element as android; this element is referenced from code by specifying R.id.android.

These elements also specify layout_width and layout_height attributes for determining how their content is laid out. Each attribute is assigned wrap_content so that the element will appear at its natural size.

ImageView specifies a layout_marginBottom attribute to identify a space separator between itself and the button that follows vertically. The space is specified as 10 dips, or density-independent pixels. These are virtual pixels that apps can use to express layout dimensions/positions in a screen density-independent way.

Density-independent pixels

Un pixel indipendente dalla densità (dip) è equivalente a un pixel fisico su uno schermo a 160 dpi, la densità di base ipotizzata da Android. In fase di esecuzione, Android gestisce in modo trasparente qualsiasi ridimensionamento delle unità dip richieste, in base alla densità effettiva dello schermo in uso. Le unità dip vengono convertite in pixel dello schermo tramite l'equazione: pixel = dip * (densità / 160) . Ad esempio, su uno schermo a 240 dpi, 1 dip equivale a 1,5 pixel fisici. Google consiglia di utilizzare unità dip per definire l'interfaccia utente della tua app per garantire la corretta visualizzazione dell'interfaccia utente su diversi schermi del dispositivo.

Scegliere e salvare un nuovo layout