Passa ai contenuti principali

Android Studio - ListView: personalizzazione della lista

In questo articolo vedremo come poter realizzare una ListView personalizzata con la possibilità di inserire immagini e testi all'interno di un singolo elemento della lista.

ESEMPIO 1:
Supponiamo di voler creare una lista con una immagine e a fianco un testo come titolo ed un testo come descrizione

L'esempio si compone di questi file:
  • File activity_main.xml - layout principale dell'applicazione
  • File mylist.xml - layout del singolo elemento all'interno della lista
  • File MainActivity.kt - codice
Ecco come si presenta il file activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Ecco come si presenta il file mylist.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/iconIv"
android:src="@color/colorAccent"
android:layout_width="80dp"
android:layout_height="80dp" />
<LinearLayout
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<TextView
android:id="@+id/titleTv"
android:text="Title"
android:textSize="15sp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/descTv"
android:text="Description"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
view raw mylist.xml hosted with ❤ by GitHub
Ora all'interno del codice bisogna inserire alcune righe di codice che permettono la creazione della lista e creare due classi per la gestione della lista personalizzata
//inizializzazione della variabile listView
lateinit var listView : ListView
//...........all'interno della funzione onCreate().........................
listView = findViewById(R.id.listView)
val list = mutableListOf<Model>()
list.add(Model("Titolo uno", "Descrizione uno...", R.drawable.immagine1))
list.add(Model("Titolo due", "Descrizione due...", R.drawable.immagine2))
list.add(Model("Titolo tre", "Descrizione tre...", R.drawable.immagine3))
list.add(Model("Titolo quattro", "Descrizione quattro...", R.drawable.immagine4))
listView.adapter = MyListAdapter(this, R.layout.mylist, list)
listView.setOnItemClickListener{ parent, view, position, id ->
if (position==0){
Toast.makeText(this, "Elemento 1", Toast.LENGTH_SHORT).show()
}
if (position==1){
Toast.makeText(this, "Elemento 2", Toast.LENGTH_SHORT).show()
}
if (position==2){
Toast.makeText(this, "Elemento 3", Toast.LENGTH_SHORT).show()
}
if (position==3){
Toast.makeText(this, "Elemento 4", Toast.LENGTH_SHORT).show()
}
}
//...........altro codice può essere inserito qui di seguito................
//inserire questa Classe al di fuori della Classe principale (MainActivity)
//è possibile creare una Classe con il nome "MyListAdapter.kt"
class MyListAdapter(private var mCtx: Context, private var resource:Int, private var items:List<Model>)
: ArrayAdapter<Model>( mCtx , resource , items ){
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val layoutInflater : LayoutInflater = LayoutInflater.from(mCtx)
val view : View = layoutInflater.inflate(resource, null )
val imageView : ImageView = view.findViewById(R.id.iconIv)
val textView : TextView = view.findViewById(R.id.titleTv)
val textView1 : TextView = view.findViewById(R.id.descTv)
val person : Model = items[position]
imageView.setImageDrawable(mCtx.resources.getDrawable(person.photo))
textView.text = person.title
textView1.text = person.desc
return view
}
}
//inserire questa Classe al di fuori della Classe principale (MainActivity)
//è possibile creare una Classe con il nome "Model.kt"
class Model(val title:String, val desc:String, val photo:Int )
Ecco come si presenta il file MainActivity.kt
package com.dm.tutoriallistview12
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
lateinit var listView : ListView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listView = findViewById(R.id.listView)
val list = mutableListOf<Model>()
list.add(Model("Titolo uno", "Descrizione uno...", R.drawable.immagine1))
list.add(Model("Titolo due", "Descrizione due...", R.drawable.immagine2))
list.add(Model("Titolo tre", "Descrizione tre...", R.drawable.immagine3))
list.add(Model("Titolo quattro", "Descrizione quattro...", R.drawable.immagine4))
listView.adapter = MyListAdapter(this, R.layout.mylist, list)
listView.setOnItemClickListener{ parent, view, position, id ->
if (position==0){
Toast.makeText(this, "Elemento 1", Toast.LENGTH_SHORT).show()
}
if (position==1){
Toast.makeText(this, "Elemento 2", Toast.LENGTH_SHORT).show()
}
if (position==2){
Toast.makeText(this, "Elemento 3", Toast.LENGTH_SHORT).show()
}
if (position==3){
Toast.makeText(this, "Elemento 4", Toast.LENGTH_SHORT).show()
}
}
}
}
class MyListAdapter(private var mCtx: Context, private var resource:Int, private var items:List<Model>)
: ArrayAdapter<Model>( mCtx , resource , items ){
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val layoutInflater : LayoutInflater = LayoutInflater.from(mCtx)
val view : View = layoutInflater.inflate(resource, null )
val imageView : ImageView = view.findViewById(R.id.iconIv)
val textView : TextView = view.findViewById(R.id.titleTv)
val textView1 : TextView = view.findViewById(R.id.descTv)
val person : Model = items[position]
imageView.setImageDrawable(mCtx.resources.getDrawable(person.photo))
textView.text = person.title
textView1.text = person.desc
return view
}
}
class Model(val title:String, val desc:String, val photo:Int )

Ecco un video dimostrativo


Download Project
Download file APK


ESEMPIO 2:
Rispetto all'ESEMPIO 1, questo ha un maggiore controllo dell'elemento selezionato in quanto sono stati creati tre Array diversi in base agli elementi che compongono la singola voce della lista.
L'esempio si compone di questi file:
  • File activity_main.xml - layout principale dell'applicazione
  • File mylist.xml - layout del singolo elemento all'interno della lista
  • File MainActivity.kt - codice
Ecco come si presenta il file activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</ListView>
</RelativeLayout>
Ecco come si presenta il file mylist.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dp">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp">
<ImageView android:id="@+id/fImage"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@color/colorAccent"/>
<TextView
android:id="@+id/fName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_toEndOf="@+id/fImage"
android:layout_toRightOf="@+id/fImage"
android:text="Text" />
<TextView android:id="@+id/fDesc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignStart="@+id/fName"
android:layout_alignLeft="@+id/fName"
android:layout_below="@+id/fName"
android:text="Text" />
</RelativeLayout>
</RelativeLayout>
view raw mylist2.xml hosted with ❤ by GitHub
Ora all'interno del codice bisogna inserire alcune righe di codice che permettono la creazione della lista e creare una classe per la gestione della lista personalizzata
lateinit var listView : ListView
//Array delle immagini
private var image = intArrayOf(R.drawable.immagine1, R.drawable.immagine2, R.drawable.immagine3, R.drawable.immagine4)
//Array dei titoli
private var names = arrayOf("Titolo uno", "Titolo due", "Titolo tre", "Titolo quattro")
//Array delle descrizioni
private var desc = arrayOf("Descrizione uno", "Descrizione due", "Descrizione tre", "Descrizione quattro")
//...........all'interno della funzione onCreate().........................
listView = findViewById(R.id.listview)
/*dichiarazione della variabile customAdptor associata alla classe "CustomAdptor"
creata al di fuori della classe "MainActivity"*/
val customAdptor = CustomAdptor(this)
listView.adapter = customAdptor
listView.setOnItemClickListener{ parent, view, position, id ->
/*avendo creato gli Array è possibile risalire al nome del titolo dell'elemento cliccato
semplicemente utilizzando la funzione di lettura degli Array: nomeArray[indice]
che in questo caso è names[position]*/
Toast.makeText(this, "Hai cliccato:"+"\n"+ names[position] + "\n" + desc[position], Toast.LENGTH_SHORT).show()
}
//...........altro codice può essere inserito qui di seguito................
//inserire questa Classe al di fuori della Classe principale (MainActivity)
//è possibile creare una Classe con il nome "CustomAdptor.kt"
class CustomAdptor(private val context: Activity): BaseAdapter() {
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val inflater = context.layoutInflater
val view1 = inflater.inflate(R.layout.mylist,null)
val fimage = view1.findViewById<ImageView>(R.id.fImage)
val fName = view1.findViewById<TextView>(R.id.fName)
val fDesc = view1.findViewById<TextView>(R.id.fDesc)
fimage.setImageResource(image[p0])
fName.text = names[p0]
fDesc.text = desc[p0]
return view1
}
override fun getItem(p0: Int): Any {
return image[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return image.size
}
}
Ecco come si presenta il file MainActivity.kt
package com.dm.tutoriallistview13
import android.app.Activity
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.widget.*
lateinit var listView : ListView
//Array delle immagini
private var image = intArrayOf(R.drawable.immagine1, R.drawable.immagine2, R.drawable.immagine3, R.drawable.immagine4)
//Array dei titoli
private var names = arrayOf("Titolo uno", "Titolo due", "Titolo tre", "Titolo quattro")
//Array delle descrizioni
private var desc = arrayOf("Descrizione uno", "Descrizione due", "Descrizione tre", "Descrizione quattro")
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
listView = findViewById(R.id.listview)
/*dichiarazione della variabile customAdptor associata alla classe "CustomAdptor"
creata al di fuori della classe "MainActivity"*/
val customAdptor = CustomAdptor(this)
listView.adapter = customAdptor
listView.setOnItemClickListener{ parent, view, position, id ->
/*avendo creato gli Array è possibile risalire al nome del titolo dell'elemento cliccato
semplicemente utilizzando la funzione di lettura degli Array: nomeArray[indice]
che in questo caso è names[position]*/
Toast.makeText(this, "Hai cliccato:"+"\n"+ names[position] + "\n" + desc[position], Toast.LENGTH_SHORT).show()
}
}
}
//inserire questa Classe al di fuori della Classe principale (MainActivity)
//è possibile creare una Classe con il nome "CustomAdptor.kt"
class CustomAdptor(private val context: Activity): BaseAdapter() {
override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
val inflater = context.layoutInflater
val view1 = inflater.inflate(R.layout.mylist,null)
val fimage = view1.findViewById<ImageView>(R.id.fImage)
val fName = view1.findViewById<TextView>(R.id.fName)
val fDesc = view1.findViewById<TextView>(R.id.fDesc)
fimage.setImageResource(image[p0])
fName.text = names[p0]
fDesc.text = desc[p0]
return view1
}
override fun getItem(p0: Int): Any {
return image[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return image.size
}
}

Ecco un video dimostrativo


Download Project
Download file APK


Commenti

Post popolari in questo blog

Android Studio - Impostare lingua app

In questo articolo vedremo come poter selezionare la lingua all'interno della nostra app. Nel precedente articolo in cui si parlava del file string.xml , la lingua dell'app veniva selezionata automaticamente in base alle impostazioni del dispositivo, mentre qui vedremo come poter selezionare a proprio piacimento la lingua che dovrà avere la nostra app indipendentemente dall'impostazione del dispositivo. Per prima cosa creare il layout Ecco un esempio do come può essere il file activity_main.xml Ora creare le stringhe di testo all'interno del file string.xml Ora creare la traduzione del file string.xml nelle varie lingua come descritto in questo articolo Il risultato sarà una serie di file string.xml delle varie lingue impostate. Ora queste di seguito sono tre funzioni che servono per: selezione della lingua salvataggio della selezione nelle preferenze dell'app caricamento della lingua quando si avvia l'app Ecco come si presenta il file Main...

Android Studio - Rinominare il progetto

Rinominare il progetto Android Studio ATTENZIONE!: non eseguire questa procedura se l'app è stata pubblicata su Google Play Store Quando si vuole cambiare nome al progetto: nome cartella in cui è contenuto il progetto package name bisogna eseguire questi passaggi: Andare nella cartella dove è contenuto il progetto Creare una copia del progetto in questione Rinominare la cartella copiata con il nome dell'app (non usare spazi tra le parole) Ora è necessario dire ad Android Studio il nome del nuovo progetto  Aprire Android Studio Aprire il progetto creato in precedenza Una volta caricato il progetto cliccare Build Cliccare Clean Project Attendere che venga eseguito il processo di "pulitura" Cliccare ancora su Build Cliccare su Rebuild Project Attendere che venga ricostruito il progetto Ora aprire la cartella app fino a visualizzare la cartella java Cliccare sull'ingranaggio  Deselezionare la voce Compact Middle Packa...

Arduino - Lettura tensione potenziometro e display LCD

Leggere il valore di un poteziometro (parte 2) Oggi vedremo come leggere il valore in tensione di un potenziometro collegato al pin Analogico A0 di Arduino.