Condizionali in Kotlin - parte 2

In questo codelab, aggiungerai immagini di dadi alla tua app Android Dice Roller esistente. Assicurati di completare il codelab precedente sulla costruzione della base dell'app Dice Roller.

Invece del valore del dado in un TextView, la tua app mostrerà l'immagine appropriata del numero di lati che è stato lanciato. Sarà un'esperienza utente molto più visiva e migliorata per la tua app.

Ti verrà fornito un link per scaricare le immagini dei dadi e le aggiungerai come risorse nella tua app. Per scrivere il codice per l'immagine del dado, utilizzerai una dichiarazione when in Kotlin.

Prerequisiti

  • Completato il codelab su Crea un'app Android a dadi con un pulsante.
  • Possibilità di scrivere istruzioni di flusso di controllo (if / else, when istruzioni).
  • È in grado di aggiornare l'interfaccia utente dell'app in base all'input dell'utente (modifica il file MainActivity.kt).
  • È in grado di aggiungere un listener di clic a un Button.
  • È in grado di aggiungere risorse di immagine a un'app Android.

Obiettivi didattici

  • Come aggiornare ImageView quando l'app è in esecuzione.
  • Come personalizzare il comportamento dell'app in base a condizioni diverse (tramite un'istruzione when).

Cosa devi creare

  • App Android Dadi per lancio con un Button che tira un dado e aggiorna l'immagine sullo schermo.

Cosa serve

  • Un computer su cui è installato Android Studio.
  • Per scaricare le immagini dei dadi è necessaria una connessione a Internet.

In questa attività, sostituirai la TextView nel tuo layout con una ImageView che mostrerà un'immagine del risultato del lancio di dadi.

Apri l'app Rullo dadi

  1. Apri ed esegui l'app Dice Roller dall'app Android Dice Roller con un pulsante in Android Studio.
    L'app dovrebbe avere il seguente aspetto.

  1. Apri activity_main.xml (app > res > layout > activity_main.xml).
    Viene aperto l'editor di layout.

Eliminazione di TextView

  1. Nell'Editor layout, seleziona la TextView nella struttura dei componenti.
  1. Fai clic con il pulsante destro del mouse e scegli Elimina o premi il tasto Delete.
  2. Per il momento, ignora l'avviso su Button. Lo risolverai nel passaggio successivo.

Aggiungere un elemento ImageView al layout

  1. Trascina un ImageView dalla Tavolozza nella visualizzazione Design, posizionandolo sopra il Button.

  1. Nella finestra di dialogo Scegli una risorsa, seleziona avatar in Dati di esempio. Questa è l'immagine temporanea che utilizzerai finché non aggiungi le immagini dei dadi nell'attività successiva.

  1. Premi OK. La vista Design dell'app dovrebbe avere questo aspetto.

  1. Nella struttura dei componenti vengono visualizzati due errori. L'elemento Button non è vincolato in verticale e l'elemento ImageView non è né verticale né orizzontale.

L'elemento Button non è vincolato in verticale perché hai rimosso l'elemento TextView al di sotto del quale era posizionato in origine. Ora devi posizionare ImageView e Button sotto il campo.

Posiziona i pulsanti ImageView e Pulsante

Devi centrare verticalmente ImageView nella schermata, indipendentemente da dove si trova Button.

  1. Aggiungi vincoli orizzontali a ImageView. Collega il lato sinistro di ImageView al bordo sinistro del dispositivo ConstraintLayout principale.
  2. Collega il lato destro di ImageView al bordo destro del dispositivo principale.
    In questo modo il centro verrà centrato orizzontalmente all'interno di ImageView.

  1. Aggiungi un vincolo verticale a ImageView, collegando la parte superiore di ImageView a quella principale.
    ImageView scorre fino alla parte superiore di ConstraintLayout.
  2. Aggiungi un vincolo di verticale al Button, collegando la parte superiore del Button alla parte inferiore del ImageView.
    Il Button scorrerà verso l'alto sotto il ImageView.
  3. Ora seleziona di nuovo ImageView e aggiungi un vincolo di verticale che collega la parte inferiore della ImageView alla parte inferiore dell'elemento principale.
    In questo modo il ImageView viene posizionato in verticale nel ConstraintLayout.

Ora tutti gli avvisi sui vincoli dovrebbero essere eliminati.

Dopodiché, la vista Design dovrebbe avere questo aspetto, con ImageView al centro e Button immediatamente sotto.

È possibile che su ImageView nell'albero dei componenti venga visualizzato un avviso per aggiungere una descrizione dei contenuti al ImageView. Per il momento non ti preoccupare di questo avviso, perché in seguito configurerai la descrizione dei contenuti dell'elemento ImageView in base all'immagine del dado visualizzata. Questa modifica verrà apportata nel codice Kotlin.

In questa attività scaricherai alcune immagini di dadi e le aggiungerai alla tua app.

Scarica le immagini dei dadi

  1. Apri questo URL per scaricare un file ZIP di immagini di dadi sul computer. Attendi il completamento del download.
  2. Cerca il file sul computer (probabilmente nella cartella Download).
  3. Fai doppio clic sul file ZIP per decomprimerlo. Viene creata una nuova cartella DiceImages contenente 6 file immagine di dadi, che mostrano i valori da 1 a 6 dadi.

Aggiungi immagini di dadi all'app

  1. In Android Studio, fai clic su Visualizza > Strumento Windows > Resource Manager nei menu oppure fai clic sulla scheda Resource Manager a sinistra della finestra Progetto.
  2. Fai clic sul + sotto Gestione risorse e seleziona Importa disegni. Si apre un browser di file.

  1. Trova e seleziona i file con sei immagini a dadi. Puoi selezionare il primo file, quindi, tenendo premuto il tasto Shift, seleziona gli altri file.
  2. Fai clic su Apri.
  1. Fai clic su Avanti, quindi su Importa per confermare che vuoi importare le sei risorse.

  1. Se i file sono stati importati correttamente, le sei immagini dovrebbero apparire nell'elenco Drawable della tua app.

Ottimo! Nella prossima attività, utilizzerai queste immagini nella tua app.

Importante: - Potrai fare riferimento a queste immagini nel tuo codice Kotlin con i relativi ID risorsa:

  • R.drawable.dice_1
  • R.drawable.dice_2
  • R.drawable.dice_3
  • R.drawable.dice_4
  • R.drawable.dice_5
  • R.drawable.dice_6

Sostituisci l'immagine avatar di esempio

  1. Nell'Editor di progettazione, seleziona ImageView.
  2. In Attributi nella sezione Attributi dichiarati, trova l'attributo strumento srcCompat, che è impostato sull'immagine avatar.

Ricorda che gli strumenti srcCompat utilizzano l'immagine fornita solo nella visualizzazione Design di Android Studio. L'immagine viene mostrata agli sviluppatori solo durante la creazione dell'app, ma non verrà visualizzata quando esegui effettivamente l'app sull'emulatore o su un dispositivo.

  1. Fai clic sulla piccola anteprima dell'avatar. Si apre una finestra di dialogo per scegliere una nuova risorsa da utilizzare per ImageView.

  1. Seleziona l'elemento dice_1 che puoi tracciare e fai clic su OK.

Wow! L'elemento ImageView occupa l'intero schermo.

Dopodiché modificherai la larghezza e l'altezza del ImageView, in modo che non nasconda Button.

  1. Nella finestra Attributi sotto il Widget Vincoli, individua gli attributi layout_width e layout_height. Al momento sono impostati su wrap_content, il che significa che il ImageView sarà alto e largo quanto i contenuti (l'immagine di origine) al suo interno.
  2. Devi invece impostare una larghezza fissa di 160 dp e un'altezza fissa di 200 dp sul ImageView. Premi Invio.

    Ora ImageView è molto più piccolo.


Potresti notare che il valore Button è troppo vicino all'immagine.

  1. Aggiungi un margine superiore al pulsante di 16 dp impostandolo nel Widget vincolo.

Una volta aggiornata la vista Design, l'app diventa ancora più bella.

Cambia l'immagine del dado quando viene fatto clic sul pulsante

Il layout è stato corretto, ma è necessario aggiornare la classe MainActivity per utilizzare le immagini dei dadi.

Si è verificato un errore nell'app nel file MainActivity.kt. Se provi a eseguire l'app, verrà visualizzato questo errore di build:

Infatti, il codice fa ancora riferimento a TextView che hai eliminato dal layout.

  1. Apri MainActivity.kt (app > java > com.example.diceroller > MainActivity.kt)

Il codice fa riferimento a R.id.textView, ma Android Studio non lo riconosce.

  1. All'interno del metodo rollDice(), seleziona un codice che faccia riferimento a TextView ed eliminalo.
// Update the TextView with the dice roll
val resultTextView: TextView = findViewByID(R.id.textView)
resultTextView.text = dice.roll().toString()
  1. Ancora in rollRice(), crea una nuova variabile denominata diceImage di tipo ImageView. Impostalo uguale a ImageView dal layout. Utilizza il metodo findViewById() e trasmetti l'ID risorsa per ImageView, R.id.imageView, come argomento di input.
val diceImage: ImageView = findViewById(R.id.imageView)

Se ti stai chiedendo come capire l'ID risorsa esatto di ImageView, controlla l'id nella parte superiore della finestra Attributi.

Quando fai riferimento a questo ID risorsa nel codice Kotlin, assicurati di digitarlo esattamente nello stesso modo (maiuscole e maiuscole, senza spazi). In caso contrario, Android Studio mostrerà un errore.

  1. Aggiungi questa riga di codice per verificare che sia possibile aggiornare correttamente ImageView quando viene fatto clic sul pulsante. Il lancio del dado non sarà sempre "2"; tuttavia, utilizza l'immagine dice_2 per verificare.
diceImage.setImageResource(R.drawable.dice_2)

Questo codice chiama il metodo setImageResource() su ImageView, trasmettendo l'ID risorsa dell'immagine dice_2. Questa operazione aggiornerà ImageView sullo schermo per visualizzare l'immagine dice_2.

Il metodo rollDice() dovrebbe avere il seguente aspetto:

private fun rollDice() {
    val dice = Dice(6)
    val diceRoll = dice.roll()
    val diceImage: ImageView = findViewById(R.id.imageView)
    diceImage.setImageResource(R.drawable.dice_2)
}
  1. Esegui l'app per verificare che venga eseguita senza errori.

L'app deve iniziare con una schermata vuota, eccetto il pulsante Roll.

Dopo aver toccato il pulsante, viene visualizzata un'immagine del dado che mostra il valore 2. Sì!

Hai potuto modificare l'immagine in base al tocco del pulsante. Ci stai avvicinando!

È ovvio che il risultato del dado non sia sempre un 2. Usa la logica del flusso di controllo appresa nel codelab Aggiungi un comportamento condizionale per diversi tiri a dadi in modo che l'immagine del dado appropriata venga visualizzata sullo schermo a seconda del tiro casuale dei dadi.

Prima di iniziare a digitare il codice, pensa concettualmente al comportamento dell'app scrivendo pseudocode che descriva l'operazione. Ad esempio:

Se l'utente fa scorrere un elemento 1, mostra l'immagine dice_1.

Se l'utente esegue il rollback di 2, viene visualizzata l'immagine dice_2.

ecc...

Lo pseudocodice sopra può essere scritto con le istruzioni if / else in Kotlin in base al valore del tiro di dado.

if (diceRoll == 1) {
   diceImage.setImageResource(R.drawable.dice_1)
} else if (diceRoll == 2) {
   diceImage.setImageResource(R.drawable.dice_2)
}
 ...

Tuttavia, scrivere if / else per ogni caso è piuttosto ripetitivo. La stessa logica può essere espressa in modo più semplice con un'istruzione when. Questo messaggio è più conciso (meno codice). Utilizza questo approccio nella tua app.

when (diceRoll) {
   1 -> diceImage.setImageResource(R.drawable.dice_1)
   2 -> diceImage.setImageResource(R.drawable.dice_2)
   ...

Aggiorna il metodo rollDice()

  1. Nel metodo rollDice(), elimina ogni volta la riga di codice che imposta l'ID risorsa dell'immagine su dice_2 immagine.
diceImage.setImageResource(R.drawable.dice_2)
  1. Sostituiscila con un'istruzione when che aggiorni ImageView in base al valore diceRoll.
   when (diceRoll) {
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }

Al termine delle modifiche, il metodo rollDice() dovrebbe avere il seguente aspetto.

private fun rollDice() {
   val dice = Dice(6)
   val diceRoll = dice.roll()

   val diceImage: ImageView = findViewById(R.id.imageView)

   when (diceRoll) {
       1 -> diceImage.setImageResource(R.drawable.dice_1)
       2 -> diceImage.setImageResource(R.drawable.dice_2)
       3 -> diceImage.setImageResource(R.drawable.dice_3)
       4 -> diceImage.setImageResource(R.drawable.dice_4)
       5 -> diceImage.setImageResource(R.drawable.dice_5)
       6 -> diceImage.setImageResource(R.drawable.dice_6)
   }
}
  1. Esegui l'app. Fai clic sul pulsante Rotola per cambiare l'immagine del dado in altri valori oltre a 2. Funziona!

Ottimizza il codice

Se vuoi scrivere codice ancora più conciso, puoi apportare la seguente modifica al codice. Non ha alcun impatto visibile sull'utente della tua app, ma renderà il tuo codice più breve e meno ripetitivo.

Potresti aver notato che la chiamata al numero diceImage.setImageResource() appare 6 volte nel tuo estratto conto una volta.

when (diceRoll) {
    1 -> diceImage.setImageResource(R.drawable.dice_1)
    2 -> diceImage.setImageResource(R.drawable.dice_2)
    3 -> diceImage.setImageResource(R.drawable.dice_3)
    4 -> diceImage.setImageResource(R.drawable.dice_4)
    5 -> diceImage.setImageResource(R.drawable.dice_5)
    6 -> diceImage.setImageResource(R.drawable.dice_6)
}

L'unica cosa che cambia in ciascun caso è l'ID risorsa utilizzato. Ciò significa che puoi creare una variabile per archiviare l'ID della risorsa da utilizzare. A questo punto, puoi chiamare diceImage.setImageResource()una sola volta nel codice e trasmettere l'ID risorsa corretto.

  1. Sostituisci il codice riportato sopra con il codice seguente.
val drawableResource = when (diceRoll) {
   1 -> R.drawable.dice_1
   2 -> R.drawable.dice_2
   3 -> R.drawable.dice_3
   4 -> R.drawable.dice_4
   5 -> R.drawable.dice_5
   6 -> R.drawable.dice_6
}

diceImage.setImageResource(drawableResource)

Un nuovo concetto in questo caso è che un'espressione when può effettivamente restituire un valore. Con questo nuovo snippet di codice, l'espressione when restituisce l'ID risorsa corretto, che verrà memorizzato nella variabile drawableResource. Puoi quindi utilizzare tale variabile per aggiornare la risorsa immagine visualizzata.

  1. Nota che ora il testo when è sottolineato in rosso. Se passi il mouse sopra al puntatore, verrà visualizzato il messaggio di errore: 'when'expression deve essere esaustiva, aggiungi 'else'ramo.

L'errore è dovuto al fatto che il valore dell'espressione when è assegnato a drawableResource, pertanto when deve essere esaustivo: deve gestire tutti i casi possibili in modo che venga sempre restituito un valore, anche se passi a un dado a 12 lati. Android Studio suggerisce di aggiungere un ramo else. Per risolvere il problema, modifica la richiesta di assistenza per 6 in else. Le richieste di assistenza per 1 fino a 5 sono le stesse, ma tutti gli altri, compreso 6, sono gestiti da else.

val drawableResource = when (diceRoll) {
   1 -> R.drawable.dice_1
   2 -> R.drawable.dice_2
   3 -> R.drawable.dice_3
   4 -> R.drawable.dice_4
   5 -> R.drawable.dice_5
   else -> R.drawable.dice_6
}

diceImage.setImageResource(drawableResource)
  1. Esegui l'app per assicurarti che funzioni ancora correttamente. Assicurati di testarlo a sufficienza per assicurarti che tutti i numeri siano visualizzati con le immagini da da 1 a 6.

Impostare una descrizione dei contenuti appropriata su ImageView

Ora che hai sostituito il numero arrotolato con un'immagine, gli screen reader non possono più sapere quale numero viene rilasciato. Per risolvere il problema, dopo aver aggiornato la risorsa immagine, aggiorna la descrizione dei contenuti del ImageView. Si tratta di una descrizione testuale degli elementi visualizzati in ImageView, in modo che gli screen reader possano descriverli.

diceImage.contentDescription = diceRoll.toString()

Gli screen reader possono leggere ad alta voce la descrizione di questo contenuto, quindi se l'immagine viene visualizzata sullo schermo, la descrizione del contenuto verrà letta ad alta voce come "6".

Crea un'esperienza di lancio più utile

Quando l'utente apre l'app per la prima volta, è vuota (tranne che per il pulsante Roll), che ha un aspetto insolito. Gli utenti potrebbero non sapere cosa aspettarsi, quindi modifica l'interfaccia utente in modo da visualizzare un lancio casuale di dadi quando avvii l'app e crei per la prima volta il Activity. Quindi è più probabile che gli utenti capiscano che se tocchi il pulsante Rotolo, ottieni un lancio di dadi.

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val rollButton: Button = findViewById(R.id.button)
   rollButton.setOnClickListener { rollDice() }

   // Do a dice roll when the app starts
   rollDice()
}

Commenta il codice

Aggiungi alcuni commenti al codice per descrivere ciò che accade nel codice che hai scritto.

Dopo aver apportato tutte queste modifiche, questo potrebbe essere il metodo rollDice().

/**
* Roll the dice and update the screen with the result.
*/
private fun rollDice() {
   // Create new Dice object with 6 sides and roll the dice
   val dice = Dice(6)
   val diceRoll = dice.roll()

   // Find the ImageView in the layout
   val diceImage: ImageView = findViewById(R.id.imageView)

   // Determine which drawable resource ID to use based on the dice roll
   val drawableResource = when (diceRoll) {
       1 -> R.drawable.dice_1
       2 -> R.drawable.dice_2
       3 -> R.drawable.dice_3
       4 -> R.drawable.dice_4
       5 -> R.drawable.dice_5
       else -> R.drawable.dice_6
   }

   // Update the ImageView with the correct drawable resource ID
   diceImage.setImageResource(drawableResource)

   // Update the content description
   diceImage.contentDescription = diceRoll.toString()
}

Per il file MainActivity.kt completo, consulta il codice della soluzione su GitHub collegato di seguito.

Ottimo lavoro! Ora puoi portare questa app alla prossima notte di gioco con i tuoi amici.

Il codice della soluzione per questo codelab è incluso nel progetto e nel modulo mostrati di seguito.

Per recuperare il codice per questo codelab da GitHub e aprirlo in Android Studio, procedi nel seguente modo:

  1. Avvia Android Studio.
  2. Nella finestra Ti diamo il benvenuto in Android Studio, fai clic su Controlla il progetto dal controllo della versione.
  3. Scegli Git.

  1. Nella finestra di dialogo Clona repository, incolla l'URL del codice fornito nella casella URL.
  2. Fai clic sul pulsante Test, attendi e assicurati che sia presente il fumetto verde che indica la connessione riuscita.
  3. (Facoltativo) Modifica la Directory in modo da utilizzare un valore diverso da quello predefinito suggerito.

  1. Fai clic su Clona. Android Studio inizia a recuperare il codice.
  2. Nella finestra popup Pagamento da controllo versione, fai clic su .

  1. Attendi che si apra Android Studio.
  2. Seleziona il modulo corretto per il codice di avvio o la soluzione del codelab.

  1. Fai clic sul pulsante Esegui per creare ed eseguire il tuo codice.
  • Utilizza setImageResource() per modificare l'immagine visualizzata in un ImageView
  • Utilizza istruzioni di flusso di controllo come espressioni if / else o espressioni when per gestire diversi casi nella tua app, ad esempio mostrando immagini diverse in circostanze diverse.

Segui questi passaggi:

  1. Aggiungi un altro dado all'app, in modo che un pulsante Lancia fornisca due risultati da dadi. Quanti ImageViews avrai bisogno per il tuo layout? Quali saranno le conseguenze per il codice MainActivity.kt?

Controllare il lavoro:

L'app completata dovrebbe essere eseguita senza errori e mostrare i due dadi.