Android:如何在这个 ListView 中设置图像?
Posted
技术标签:
【中文标题】Android:如何在这个 ListView 中设置图像?【英文标题】:Android: How to set the image in this ListView? 【发布时间】:2013-08-30 05:51:40 【问题描述】:如何设置此布局中的图像?
ListView 将包含上述 3 个条目,每个图像将在 AsyncTask
中下载(见下文),文本将由预设字符串的字符串数组填充,例如
String[] values = "string one", "string two", "String three";
我希望能够首先使用下面的适配器设置所有 3 个条目的字符串内容值,然后让 AsyncTasks 在后台运行,下载并设置每个条目的图标。
字符串比图标更重要,所以我不希望用户在设置字符串之前必须等待每个图标下载。
我有一个 ListView 布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="horizontal"
android:paddingBottom="@dimen/small_8dp"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/small_8dp" >
<ImageView
android:id="@+id/logo"
android:layout_
android:layout_
android:contentDescription="@string/loading"
android:scaleType="fitXY"
android:src="@drawable/image" >
</ImageView>
<TextView
android:id="@+id/label"
android:layout_
android:layout_
android:paddingLeft="@dimen/small_8dp"
android:text="@string/loading"
android:textSize="@dimen/medium_15dp" >
</TextView>
</LinearLayout>
在布局中:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="@color/color_white"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_
android:layout_
android:entries="@array/list_headlines">
</ListView>
</LinearLayout>
我一直在使用这个自定义适配器:
private class ArticleAdapter extends ArrayAdapter<String>
private final Context context;
private final String[] values;
public ArticleAdapter(Context context, String[] values)
super(context, R.layout.list_entry, values);
this.context=context;
this.values=values;
@Override
public View getView(int position, View convertView, ViewGroup parent)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_entry,parent,false);
TextView tv = (TextView) rowView.findViewById(R.id.label);
tv.setText(values[position]);
return rowView;
LoadThumbnail AsyncTask:
protected class LoadThumbnail extends AsyncTask<String, Void, String>
private String url;
private boolean loaded; //if loaded set the bitmap image to whats downloaded
private Bitmap icon;
private int iconIndex;
public LoadThumbnail(int iconIndex, String url)
loaded = false;
this.url = url; //url of the icon to download
this.iconIndex=iconIndex; //Which icon in the listview were downloading
@Override
protected String doInBackground(String... params)
Download download = new Download(url); //My Download Class
try
icon = download.downloadImage(); //Returns A Bitmap image
loaded=true; //If no errors caught
catch (Exceptions e)
//Various Exception Handling Here
return null;
@Override
protected void onPostExecute(String result)
super.onPostExecute(result);
你能告诉我我必须适应哪些功能才能实现这一目标吗? 谢谢!
【问题讨论】:
PS 我研究了如何设置图像,如果我已经拥有所有位图,我可以做到,但我不知道如何通过后台下载来做到这一点 所以,有一件事,您需要设置图像视图(可能基于本地图像路径),如果找不到图像,请将其保留为占位符,否则将图像设置为图像视图。在 AsyncTask 的每个周期(即下载图像)之后,只需调用 Adapter.notifyDataSetChanged()。希望这会有所帮助。 你应该使用 imageDownloader 类............ 【参考方案1】:执行此操作的最简单方法是将您的图像下载到某个Collection
,然后在下载完成时通过在Adapter
上调用notifyDatasetChanged
来更新列表。
在我们开始之前 - 我不知道您的 AsyncTask
在哪里。如果它是一个单独的类,您需要使用Interface
来设置对您开始它的位置的回调。如果它是您 Adaper
中的内部类,您可以在本地执行此操作。
您要做的是将您的Adapter
设置为 (1) 检查您想要的图像是否可用 (2) 如果没有则下载图像并将其添加到集合 (3) 当图像可用时下载刷新列表(或下载所有图像时,取决于此列表的长度)。
这一切都发生在您为特定列表项设置内容时
if(logo != null)
if(imageCollection.contains(key)
logo.setImageBitmap(imageCollection.get(key));
else
thumbnailDownloader.execute;
如果您的 AsyncTask
是您的适配器的内部类,那么在 onPostExecute
中,您将 (1) 将图像添加到此集合 (2) 使用 notifyDatasetChanged
更新 ListView
。如果您的 AsyncTask
是它自己的类,您可以将图像添加到回调中的集合中,并从那里更新列表。
对于collection
,如果您使用android 内置的LruCache
会更容易,但您可以使用HashMap
或其他东西。仅取决于您的实施。
【讨论】:
asyncTask 是我的 ListFragment 类的子类,可以轻松访问任何数据,因此它可以访问 Adapter 可以访问的任何数据【参考方案2】:首先,我建议将ArticleAdapter
的引用提供给AsyncTask
。
然后在ArticleAdapter
中创建Bitmap
数组或映射,并为ArticleAdapter创建add(Bitmap bmp)
方法,将位图对象放入数组/映射中。
因为您在AsyncTask
中有引用,所以您可以在onPostExecute()
方法中调用add() 方法,并使用下载的图标Bitma
p。
然后你可以调用ArticleAdapter
的notifyDataSetChanged()
,这样它就可以刷新它的视图了。
当然,如果给定键的位图已经下载,您的适配器的getView
应该检查它的位图数组/映射。如果它的引用为null,则放置一个占位符,如果已经下载,则放置由asynctask放入array/map中的位图。
【讨论】:
我如何 notifyDataSetChanged() 肯定它必须是(某个对象)。notifyDataSetChanged() 我在 ListFragment 中工作,如果这有帮助并且没有创建我可以引用的适配器对象,我设置适配器setListAdapter(new ArticleAdapter(getActivity(), strings, icons));【参考方案3】:在 getView() 中,您应该启动一个新任务来下载该列表项的图像。将要填充的 ImageView 的引用传递给 AsyncTask,然后在 onPostExecute() 中将该 ImageView 的源设置为下载的位图(图标)。
这确实有点复杂,因为您必须处理由 ListView 回收的视图(通过取消下载图像的任务)。我喜欢使用这个库来下载和缓存图片:http://square.github.io/picasso/
【讨论】:
【参考方案4】:此答案较晚,但可能对其他人有所帮助。
在您的代码中,如果您的 AsyncTask<>
位于单独的类中,那么您可以简单地通过在适配器类中给它 ImageView
来实例化它,例如
new LoadThumbnail(imageView).execute(url);
然后在您的LoadThumbnail
类中只需在imageView
中设置位图。
我写的很粗略,请随意;
@Override
public View getView(int position, View convertView, ViewGroup parent)
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.list_entry,parent,false);
TextView tv = (TextView) rowView.findViewById(R.id.label);
ImageView imageView = (ImageView)rowView.findViewById(R.id.logo);
tv.setText(values[position]);
//Instantiate LoadThumbnail giving it imageView to set bitmap in.
new LoadThumbnail(imageView).execute(url);
return rowView;
现在在LoadThumbnail
中只需在onPostExecute()
方法中设置位图。
protected class LoadThumbnail extends AsyncTask<String, Void, Bitmap>
private ImageView imageView;
public LoadThumbnail(ImageView imageView)
this.imageView = imageView;
@Override
protected String doInBackground(String... url)
Bitmap icon = null;
Download download = new Download(url[0]); //My Download Class
try
icon = download.downloadImage(); //Returns A Bitmap image
loaded=true; //If no errors caught
catch (Exceptions e)
//Various Exception Handling Here
return icon;
@Override
protected void onPostExecute(Bitmap icon)
super.onPostExecute(icon);
//here set bitmap in imageView;
if(icon != null)
imageView.setImageBitmap(icon);
【讨论】:
以上是关于Android:如何在这个 ListView 中设置图像?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 android listview 中设置页脚以动态拉伸到底部?