Un aspetto fondamentale delle interfacce utente sono le immagini. Utilizzarle per completare l'effetto comunicativo ed informativo delle nostre applicazioni è molto importante, ma esse vanno gestite in maniera corretta, soprattutto quando devono essere scaricate direttamente dalla rete. Quest'ultima è una pratica molto comune che pone delle problematiche da tenere in considerazione: consumo dati, tempi di latenza, rallentamento della UI, codifica di formati. Il tutto potrebbe essere risolto dal programmatore sfruttando comuni classi Java o del framework Android, ma esistono librerie, spesso di terze parti, nate per ottimizzare questo tipo di lavoro, chiamate comunemente Image Loader. Ne vedremo una al lavoro nell'esempio di questa lezione: Glide. Nonostante non sia l'unica opzione esistente, essa offre particolari caratteristiche di efficienza, tanto da essere la scelta prediletta di Google. Infine, conosceremo un widget, CircleImageView, con il quale si possono visualizzare immagini in forma circolare, aspetto molto in voga nelle app moderne.
L'esempio
L'esempio che presentiamo in questa lezione è piuttosto semplice. Mostra alcune CardView, ognuna delle quali contiene un'immagine scaricata dalla rete tramite Glide, ed alcuni testi di esempio.
Il risultato finale sarà il seguente:
L'origine remota che fornirà le immagini è un servizio molto utile per le finalità di test. Si chiama lorempixel e permette di richiedere la risorsa che si desidera specificandone dimensioni e categoria di appartenenza in un URL stile REST. Noi chiederemo tre immagini di dimensione 500x400 pixel, riguardanti rispettivamente lo sport, la natura e il cibo. Gli URL per ottenere le immagini saranno i seguenti:
http://lorempixel.com/500/400/sports
http://lorempixel.com/500/400/nature
http://lorempixel.com/500/400/food
Le dipendenze di cui avremo bisogno nel progetto saranno risolte da Gradle. Queste le istruzioni che inseriremo nel build file:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:design:22.2.0'
compile 'com.android.support:appcompat-v7:22.2.0'
compile 'com.android.support:cardview-v7:22.2.0'
compile 'com.github.bumptech.glide:glide:3.6.0'
}
Richiederemo così di avere a disposizione alcune sezioni della libreria di supporto - Design Support Library, AppCompat e CardView - ma anche Glide, che verrà recuperato dai repository del progetto.
Il layout dell'interfaccia
Il layout che useremo nell'app è un LinearLayout con orientamento verticale. Al suo interno, le tre CardView saranno strutturate in questo modo: il layout interno sarà un RelativeLayout che contiene un'immagine alla quale sarà sovrapposta una TextView per mostrarne il titolo e, al di sotto, verrà collocato altro testo, di natura descrittiva.
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="center_horizontal">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
style="@style/Base.TextAppearance.AppCompat.Headline">
<ImageView
android:id="@+id/iv_card"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_card_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/iv_card"
android:layout_alignLeft="@+id/iv_card"
android:padding="10dp"
android:text="Sport"
android:textColor="@android:color/white"
android:background="#55000000"
android:textSize="@dimen/abc_text_size_headline_material" />
<TextView
android:id="@+id/tv_card"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_card_title"
android:padding="10dp"
android:text="@string/sport_ipsum" />
</RelativeLayout>
</android.support.v7.widget.CardView>
L'Activity
L'Activity come vedremo non sarà affatto complicata. Una volta caricato il layout non faremo altro che ordinare a Glide di recuperare le immagini remote, mentre i testi proverranno da risorse di tipo valore.
public class MainActivity extends AppCompatActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
final Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setSubtitle("Gestione di immagini remote");
ImageView image1= (ImageView) findViewById(R.id.image_sport);
ImageView image2= (ImageView) findViewById(R.id.image_natura);
ImageView image3= (ImageView) findViewById(R.id.image_cibo);
Glide.with(this)
.load("http://lorempixel.com/500/400/sports")
.into(image1);
Glide.with(this)
.load("http://lorempixel.com/500/400/nature")
.into(image2);
Glide.with(this)
.load("http://lorempixel.com/500/400/food")
.into(image3);
}
}
È sufficiente osservare come viene invocata la libreria Glide per apprezzarne l'utilità. Non si istanzia alcun oggetto e con il metodo load() si indica l'URL dell'immagine da prelevare. Altra cosa interessante: con il metodo into()
indicheremo in quale ImageView l'elemento deve essere collocato. Il caricamento dell'immagine avverrà in maniera asincrona, quindi l'Activity visualizzerà per prima cosa il layout e poi, non appena possibile, verrà recuperata l'immagine e collocata nel widget opportuno.
Immagini circolari
Ultimamente, molte app mostrano le immagini in forma circolare. Si pensi, ad esempio, alla lista dei contatti di Whatsapp:
Quella che presentiamo in questa lezione è una libreria, il cui codice è disponibile su GitHub, che mette a disposizione un controllo, CircleImageView, in grado di mostrare un'immagine in forma circolare.
Per includerla nel progetto è sufficiente risolvere la dipendenza con Gradle.
dependencies {
...
...
compile 'de.hdodenhof:circleimageview:1.3.0'
}
Il controllo verrà usato con l'inclusione del relativo codice nel layout XML:
<de.hdodenhof.circleimageview.CircleImageView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/profile_image"
android:layout_width="96dp"
android:layout_height="96dp"
android:src="@drawable/profile"
app:border_width="2dp"
app:border_color="#FF000000"/>
La sorgente dell'immagine viene impostata tramite l'attributo src
, che possiamo sfruttare in congiunzione con Glide, al quale passeremo l'ID assegnato al widget.
Il codice d’esempio visto fin qui è allegato a questa lezione, e liberamente scaricabile.