Quand des données provenant d’une Base de Données doivent être affichées sous forme de liste on utilise le composant ListView qui va chercher les informations via un « adapter ».
Définition des layouts :
Un layout est nécessaire pour afficher les lignes de la liste
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/tvPriority"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
/>
<ImageView
android:layout_width="50px"
android:layout_height="50px"
android:layout_marginLeft="5px"
android:layout_marginRight="20px"
android:layout_marginTop="5px"
android:id="@+id/imageIcon" />
</LinearLayout>
Un autre pour afficher la liste
<?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" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".AfficList">
<TextView android:text="Liste des icones"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/listViewIcon"
android:layout_below="@+id/textView"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginRight="119dp"
android:layout_marginEnd="119dp" />
</RelativeLayout>
Définition de la base de données :
Ecrivez une classe DbHelper, attention la base de données doit avoir un champ _id de type INTEGER PRIMARY KEY AUTOINCREMENT
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "dbnumtel.db";
private static final int DATABASE_VERSION = 1;
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS contact ( " +
"_id INTEGER PRIMARY KEY AUTOINCREMENT," +
"nom TEXT," +
"numtel TEXT," +
"normtel TEXT," +
"idico INTEGER)");
}
public static long CompteEnr(SQLiteDatabase db) {
Log.d("Base", "Nb enr=" + String.valueOf(DatabaseUtils.queryNumEntries(db, "contact")));
return DatabaseUtils.queryNumEntries(db, "contact");
}
public static long insertContact(SQLiteDatabase db, String sNom, String sNumTel, String sNormTel, int nIdIco) {
ContentValues values = new ContentValues();
values.put("nom", sNom);
values.put("numtel", sNumTel);
values.put("normtel", sNormTel);
values.put("idico", nIdIco);
return db.insert("contact", null, values);
}
}
Activité principale :
Attention, le chargement de la base de données peut prendre du temps, il est préférable, pour les tables volumineuse de procéder au chargement à l’aide d’un handler :
new Handler().post(new Runnable() {
@Override
public void run() {
customAdapter = new CustomCursorAdapter(MyActivity.this, databaseHelper.getAllData());
listView.setAdapter(customAdapter);
}
});
public class AfficList extends Activity {
private SQLiteDatabase dbNumTel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//--
DbHelper placeData = new DbHelper(this);
dbNumTel = placeData.getWritableDatabase();
//
setContentView(R.layout.liste_principale);
RempliListeIcones();
//
//-- Query for items from the database and get a cursor back
@SuppressLint("Recycle") Cursor todoCursor = dbNumTel.rawQuery("SELECT * FROM contact", null);
//-- Find ListView to populate
ListView lvItems = (ListView) findViewById(R.id.listViewIcon);
//-- Setup cursor adapter using cursor from last step
TodoCursorAdapter todoAdapter = new TodoCursorAdapter(this, todoCursor);
//-- Attach cursor adapter to the ListView
lvItems.setAdapter(todoAdapter);
//Enfin on met un écouteur d'évènement sur notre listView
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//on créer une boite de dialogue
AlertDialog.Builder adb = new AlertDialog.Builder(AfficList.this);
//on attribut un titre à notre boite de dialogue
adb.setTitle("Sélection Item");
//on insère un message à notre boite de dialogue, et ici on affiche le titre de l'item cliqué
adb.setMessage("Votre choix : "+position);
//on indique que l'on veut le bouton ok à notre boite de dialogue
adb.setPositiveButton("Ok", null);
//on affiche la boite de dialogue
adb.show();
}
});
}
void RempliListeIcones() {
String sNomIco;
int nIdIco;
//-- Test si c'est le premier lancement
if (DbHelper.CompteEnr(dbNumTel) == 0) {
//-- Si la base est libre on la rempli
Field[] drawables = andrologiciels.bdlistview.R.drawable.class.getFields(); //android
for (Field f : drawables) {
try {
sNomIco = f.getName();
nIdIco = getDrawable(AfficList.this, sNomIco);
//-- on a prefixé par 'x' les images du dossier drawable
if (sNomIco.substring(0, 1).equals("x")) {
Log.d("Custom", sNomIco + "(" + String.valueOf(nIdIco) + ")=" + sNomIco.substring(1, sNomIco.length()));
sNomIco = sNomIco.substring(1, sNomIco.length());
DbHelper.insertContact(dbNumTel, sNomIco, "", "", nIdIco);
} else
Log.d("Systeme", sNomIco);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
//-- Retourne l'identifiant du fichier drawable
public static int getDrawable(Context context, String name) {
Assert.assertNotNull(context);
Assert.assertNotNull(name);
return context.getResources().getIdentifier(name,
"drawable", context.getPackageName());
}
}
Gestion du click :
Il s’agit de récupérer le « curseur » et de se placer à la position correspondant au click. Le « curseur » renvoie la portion de liste affichée à l’écran. La position indique la place cliquée dans cette portion. Pour afficher les éléments du curseur il est nécessaire d’utiliser les champs indiqués dans « l’adapteur ». Exemple :
//On gére le click sur la liste principale
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//-- Récupération du curseur (layout des lignes)
Cursor cursor = (Cursor) a.getItemAtPosition(position);
String name = cursor.getString(cursor.getColumnIndex("nom"));
//on créer une boite de dialogue
AlertDialog.Builder BoxDiag = new AlertDialog.Builder(AfficList.this);
BoxDiag.setTitle("Sélection Item");
BoxDiag.setMessage("Votre choix : "+name);
BoxDiag.setPositiveButton("Ok", null);
BoxDiag.show();
}
});
Suppression d’enregistrements et mise à jour de la liste :
if (DbHelper.deleteContact(dbNumTel, name)==1)
{
cursor.requery();
todoAdapter.notifyDataSetChanged();
}
Gestion du Swipe (glisser droite/gauche) :
cf. page gesture
Références :
https://guides.codepath.com/android/Populating-a-ListView-with-a-CursorAdapter
https://tausiq.wordpress.com/2012/08/22/android-list-view-from-database-with-cursor-adapter/
http://www.tutorialsbuzz.com/2013/11/android-sqlite-database-with.html