如何在Android中的ListView中显示图像列表?

如何使用ListView显示图像列表? 我正在下载运行时的图像。 图像总数不固定。

我会从这样的事情开始(如果我的代码有问题,我当然会很感激任何评论):

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()); } } 

例如,用自己的Itemtypes(保存关于图片的信息)扩展ArrayAdapter并覆盖getView()方法,为列表中的项目准备视图。 ArrayAdapter上还有方法add()来添加项目到列表的末尾。

R.layout.items_listListView简单布局

R.layout.items_list_item是代表列表中的一个项目的布局

  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> 

六年来,这仍然是一些search的顶部。 从那以后,事情发生了很大变化。 现在,事实上的标准或多或less地使用Volley和NetworkImageView来为您处理繁重的工作。

假设你已经有你的Apaters,Loaders和ListFragments设置正确,这个官方的谷歌教程解释了如何使用NetworkImageView加载图像。 图像自动加载在后台线程中,并在UI线程上更新视图。 它甚至支持caching。

我想出了一个解决scheme,我称之为“BatchImageDownloader”已经很好地服务。 以下是如何使用它的快速总结:

  • 保持一个全局的HashMap(最好在你的Application对象中)作为可绘制对象的caching

  • 在List Adapter的getView()方法中,使用caching中的drawable来填充列表项中的ImageView。

  • 创build一个BatchImageDownloader的实例,传入你的ListView适配器

  • 为每个需要获取/显示的图像调用addUrl()

  • 完成后,调用execute()。 这会触发一个AsyncTask来获取所有的图像,并且当每个图像被提取并添加到caching中时,它刷新你的ListView(通过调用notifyDataSetChanged())

该方法具有以下优点:

  • 单个工作线程用于获取所有图像,而不是每个图像/视图的单独线程
  • 一旦获取图像,所有使用它的列表项即时更新
  • 该代码不直接访问List Item中的Image View,而是通过调用List Adapter上的notifyDataSetChanged()来触发listview刷新,而getView()实现只是将drawable从caching中取出并显示出来。 这可以避免与ListView中使用的循环View对象相关的问题。

这里是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; } } } 

要从数据库中获取数据,您需要使用SimpleCursorAdapter

我认为你可以直接将SimpleCursorAdapter绑定到一个ListView – 如果没有,你可以创build一个自定义的适配器类来扩展SimpleCursorAdapter和一个覆盖setViewValue的自定义的setViewValue

查看记事本教程,了解如何使用SimpleCursorAdapter

文件名应该与应用程序的布局文件夹中的layout_id匹配,例如:items_list_item.xml

 <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> 

这里是简单的ListView与不同的图像。首先,你必须复制不同types的图像,并将其粘贴到您的项目res / drawable-hdpi。图像应该是.png格式。 然后复制这个代码。

在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" /> </LinearLayout> 

创buildlistview_layout.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="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> </LinearLayout> 

在你的活动

 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/ int[] flags = new int[]{ R.drawable.image1, //here you have to give image name which you already pasted it in /res/drawable-hdpi/ 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); } } 

这是完整的code.you可以改变你的需要…评论欢迎

我们需要实现两个布局。 一个保存listview和另一个保存listview的行项目。 实现自己的自定义适配器。 想法是包含一个textview和一个imageview。

 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; } 

接下来我们在主要活动中实现function,以在运行时dynamic地包含图像和文本数据。 您可以将dynamic创build的文本数组和图像ID数组传递给自定义适配器的构造函数。

 Customlistadapter adapter = new Customlistadapter(this, image_id, text_name);