Comment afficher une liste d'images à l'aide de ListView? Je télécharge les images au moment de l'exécution. Le nombre total d'images n'est pas fixé.
Je commencerais par quelque chose comme ceci (et s'il y a quelque chose qui ne va pas dans mon code, j'apprécierais bien sûr tout commentaire):
public class ItemsList extends ListActivity {
private ItemsAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.items_list);
this.adapter = new ItemsAdapter(this, R.layout.items_list_item, ItemManager.getLoadedItems());
setListAdapter(this.adapter);
}
private class ItemsAdapter extends ArrayAdapter<Item> {
private Item[] items;
public ItemsAdapter(Context context, int textViewResourceId, Item[] items) {
super(context, textViewResourceId, items);
this.items = items;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.items_list_item, null);
}
Item it = items[position];
if (it != null) {
ImageView iv = (ImageView) v.findViewById(R.id.list_item_image);
if (iv != null) {
iv.setImageDrawable(it.getImage());
}
}
return v;
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
this.adapter.getItem(position).click(this.getApplicationContext());
}
}
Par exemple. étendre ArrayAdapter avec son propre type d’éléments (contenant des informations sur vos images) et la méthode de remplacement getView()
, qui prépare l’affichage des éléments de la liste. Il existe également une méthode add()
sur ArrayAdapter pour ajouter des éléments à la fin de la liste.
R.layout.items_list
est une mise en page simple avec ListView
R.layout.items_list_item
est une mise en page représentant un élément de la liste
package studRecords.one;
import Java.util.List;
import Java.util.Vector;
import Android.app.Activity;
import Android.app.ListActivity;
import Android.content.Context;
import Android.content.Intent;
import Android.net.ParseException;
import Android.os.Bundle;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.ArrayAdapter;
import Android.widget.ImageView;
import Android.widget.ListView;
import Android.widget.TextView;
public class studRecords extends ListActivity
{
static String listName = "";
static String listUsn = "";
static Integer images;
private LayoutInflater layoutx;
private Vector<RowData> listValue;
RowData rd;
static final String[] names = new String[]
{
"Name (Stud1)", "Name (Stud2)",
"Name (Stud3)","Name (Stud4)"
};
static final String[] usn = new String[]
{
"1PI08CS016","1PI08CS007","1PI08CS017","1PI08CS047"
};
private Integer[] imgid =
{
R.drawable.stud1,R.drawable.stud2,R.drawable.stud3,
R.drawable.stud4
};
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.mainlist);
layoutx = (LayoutInflater) getSystemService(
Activity.LAYOUT_INFLATER_SERVICE);
listValue = new Vector<RowData>();
for(int i=0;i<names.length;i++)
{
try
{
rd = new RowData(names[i],usn[i],i);
}
catch (ParseException e)
{
e.printStackTrace();
}
listValue.add(rd);
}
CustomAdapter adapter = new CustomAdapter(this, R.layout.list,
R.id.detail, listValue);
setListAdapter(adapter);
getListView().setTextFilterEnabled(true);
}
public void onListItemClick(ListView parent, View v, int position,long id)
{
listName = names[position];
listUsn = usn[position];
images = imgid[position];
Intent myIntent = new Intent();
Intent setClassName = myIntent.setClassName("studRecords.one","studRecords.one.nextList");
startActivity(myIntent);
}
private class RowData
{
protected String mNames;
protected String mUsn;
protected int mId;
RowData(String title,String detail,int id){
mId=id;
mNames = title;
mUsn = detail;
}
@Override
public String toString()
{
return mNames+" "+mUsn+" "+mId;
}
}
private class CustomAdapter extends ArrayAdapter<RowData>
{
public CustomAdapter(Context context, int resource,
int textViewResourceId, List<RowData> objects)
{
super(context, resource, textViewResourceId, objects);
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder holder = null;
TextView title = null;
TextView detail = null;
ImageView i11=null;
RowData rowData= getItem(position);
if(null == convertView)
{
convertView = layoutx.inflate(R.layout.list, null);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}
holder = (ViewHolder) convertView.getTag();
i11=holder.getImage();
i11.setImageResource(imgid[rowData.mId]);
title = holder.gettitle();
title.setText(rowData.mNames);
detail = holder.getdetail();
detail.setText(rowData.mUsn);
return convertView;
}
private class ViewHolder
{
private View mRow;
private TextView title = null;
private TextView detail = null;
private ImageView i11=null;
public ViewHolder(View row)
{
mRow = row;
}
public TextView gettitle()
{
if(null == title)
{
title = (TextView) mRow.findViewById(R.id.title);
}
return title;
}
public TextView getdetail()
{
if(null == detail)
{
detail = (TextView) mRow.findViewById(R.id.detail);
}
return detail;
}
public ImageView getImage()
{
if(null == i11)
{
i11 = (ImageView) mRow.findViewById(R.id.img);
}
return i11;
}
}
}
}
//mainlist.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="horizontal"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
>
<ListView
Android:id="@Android:id/list"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
/>
</LinearLayout>
Six ans plus tard, cela reste au sommet pour certaines recherches. Les choses ont beaucoup changé depuis. Maintenant, le standard de facto consiste plus ou moins à utiliser Volley et le NetworkImageView qui prend en charge le gros du travail pour vous.
En supposant que vous ayez déjà configuré correctement vos Apaters, Loaders et ListFragments, ce tutoriel google officiel ] explique comment utiliser NetworkImageView pour charger les images. Les images sont automatiquement chargées dans un fil d’arrière-plan et la vue mise à jour sur le fil d’interface utilisateur. Il supporte même la mise en cache.
Je suis venu avec une solution que j'appelle “BatchImageDownloader” qui a bien servi. Voici un bref résumé de son utilisation:
Conservez une HashMap globale (idéalement dans votre objet Application), qui sert de cache aux objets pouvant être dessinés.
Dans la méthode getView () de votre adaptateur de liste, utilisez le cache pouvant être dessiné à partir de Pour remplir le ImageView dans votre élément de liste.
Créez une instance de BatchImageDownloader en passant votre ListView Adapter
Appelez addUrl () pour chaque image à extraire/afficher
Une fois terminé, appelez execute (). Cela déclenche une AsyncTask qui extrait toutes les images Chaque fois qu'une image est extraite et ajoutée au cache, elle actualise votre liste (en appelant notifyDataSetChanged ()).
L'approche présente les avantages suivants:
Voici le code source de BatchImageDownloader:
package com.mobrite.androidutils;
import Java.io.IOException;
import Java.io.InputStream;
import Java.util.ArrayList;
import Java.util.HashMap;
import Java.util.List;
import org.Apache.http.HttpResponse;
import org.Apache.http.client.ClientProtocolException;
import org.Apache.http.client.methods.HttpGet;
import org.Apache.http.impl.client.DefaultHttpClient;
import Android.graphics.drawable.Drawable;
import Android.os.AsyncTask;
import Android.widget.BaseAdapter;
public class BatchImageDownloader extends AsyncTask<Void, Void, Void> {
List<String> imgUrls = new ArrayList<String>();
BaseAdapter adapter;
HashMap<String, Drawable> imageCache;
public BatchImageDownloader(BaseAdapter adapter,
HashMap<String, Drawable> imageCache) {
this.adapter = adapter;
this.imageCache = imageCache;
}
public void addUrl(String url) {
imgUrls.add(url);
}
@Override
protected Void doInBackground(Void... params) {
for (String url : imgUrls) {
if (!imageCache.containsKey(url)) {
Drawable bm = downloadImage(url);
if (null != bm) {
imageCache.put(url, bm);
publishProgress();
}
}
}
return null;
}
@Override
protected void onProgressUpdate(Void... values) {
adapter.notifyDataSetChanged();
}
@Override
protected void onPostExecute(Void result) {
adapter.notifyDataSetChanged();
}
public Drawable downloadImage(String url) {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(url);
try {
HttpResponse response = httpClient.execute(request);
InputStream stream = response.getEntity().getContent();
Drawable drawable = Drawable.createFromStream(stream, "src");
return drawable;
} catch (ClientProtocolException e) {
e.printStackTrace();
return null;
} catch (IllegalStateException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Voici le simple ListView avec différentes images. Tout d'abord, vous devez copier les différents types d'images et les coller dans le fichier res/drawable-hdpi de votre projet. Les images doivent être au format (.png) . Puis copiez ce code.
Dans main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="fill_parent"
Android:orientation="vertical" >
<TextView
Android:id="@+id/textview"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content" />
<ListView
Android:id="@+id/listview"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content" />
créez listview_layout.xml et collez ce code
<?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="match_parent"
Android:orientation="horizontal" >
<ImageView
Android:id="@+id/flag"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:contentDescription="@string/hello"
Android:paddingTop="10dp"
Android:paddingRight="10dp"
Android:paddingBottom="10dp" />
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<TextView
Android:id="@+id/txt"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textSize="15dp"
Android:text="TextView1" />
<TextView
Android:id="@+id/cur"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textSize="10dp"
Android:text="TextView2" />
</LinearLayout>
Dans votre activité
package com.test;
import Java.util.ArrayList;
import Java.util.HashMap;
import Java.util.List;
import Android.app.Activity;
import Android.os.Bundle;
import Android.widget.ListView;
import Android.widget.SimpleAdapter;
public class SimpleListImageActivity extends Activity {
// Array of strings storing country names
String[] countries = new String[] {
"India",
"Pakistan",
"Sri Lanka",
"China",
"Bangladesh",
"Nepal",
"Afghanistan",
"North Korea",
"South Korea",
"Japan"
};
// Array of integers points to images stored in /res/drawable-hdpi/
//here you have to give image name which you already pasted it in /res/drawable-hdpi/
int[] flags = new int[]{
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4,
R.drawable.image5,
R.drawable.image6,
R.drawable.image7,
R.drawable.image8,
R.drawable.image9,
R.drawable.image10,
};
// Array of strings to store currencies
String[] currency = new String[]{
"Indian Rupee",
"Pakistani Rupee",
"Sri Lankan Rupee",
"Renminbi",
"Bangladeshi Taka",
"Nepalese Rupee",
"Afghani",
"North Korean Won",
"South Korean Won",
"Japanese Yen"
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Each row in the list stores country name, currency and flag
List<HashMap<String,String>> aList = new ArrayList<HashMap<String,String>>();
for(int i=0;i<10;i++){
HashMap<String, String> hm = new HashMap<String,String>();
hm.put("txt", "Country : " + countries[i]);
hm.put("cur","Currency : " + currency[i]);
hm.put("flag", Integer.toString(flags[i]) );
aList.add(hm);
}
// Keys used in Hashmap
String[] from = { "flag","txt","cur" };
// Ids of views in listview_layout
int[] to = { R.id.flag,R.id.txt,R.id.cur};
// Instantiating an adapter to store each items
// R.layout.listview_layout defines the layout of each item
SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_layout, from, to);
// Getting a reference to listview of main.xml layout file
ListView listView = ( ListView ) findViewById(R.id.listview);
// Setting the adapter to the listView
listView.setAdapter(adapter);
}
}
Ceci est le code complet.Vous pouvez modifier votre besoin ... Les commentaires sont les bienvenus
Pour obtenir les données de la base de données, vous utiliseriez une SimpleCursorAdapter
.
Je pense que vous pouvez lier directement la SimpleCursorAdapter
à une ListView
; sinon, vous pouvez créer une classe d'adaptateur personnalisée qui étend SimpleCursorAdapter avec un ViewBinder
personnalisé qui remplace setViewValue
.
Regardez le Notepad tutorial pour voir comment utiliser une variable SimpleCursorAdapter
.
Le nom de fichier doit correspondre à l'identifiant de présentation qui dans cet exemple est: items_list_item.xml dans le dossier de présentation de votre application.
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="fill_parent"
Android:layout_height="wrap_content"
>
<ImageView Android:id="@+id/R.id.list_item_image"
Android:layout_width="100dip"
Android:layout_height="wrap_content" />
</LinearLayout>
Nous devons mettre en œuvre deux schémas. Un pour détenir listview et un autre pour conserver un élément de ligne de listview. Implémentez votre propre adaptateur personnalisé. L’idée est d’inclure une vue texte et une vue image.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View single_row = inflater.inflate(R.layout.list_row, null,
true);
TextView textView = (TextView) single_row.findViewById(R.id.textView);
ImageView imageView = (ImageView) single_row.findViewById(R.id.imageView);
textView.setText(color_names[position]);
imageView.setImageResource(image_id[position]);
return single_row;
}
Ensuite, nous implémentons une fonctionnalité dans l'activité principale pour inclure des images et des données textuelles de manière dynamique pendant l'exécution. Vous pouvez transmettre un tableau de texte et un tableau d'image id créés dynamiquement au constructeur de l'adaptateur personnalisé.
Customlistadapter adapter = new Customlistadapter(this, image_id, text_name);