如何在此布局中设置图像?
ListView将包含上述3个条目,每个图像将以AsyncTask
下载(见下文),文本将由预设字符串的String数组填充,例如
String[] values = {"string one", "string two", "String three"};
我希望能够首先使用下面的适配器设置所有3个条目的String内容值,然后在后台运行AsyncTasks并为每个条目设置图标。
字符串比图标更重要,所以我不希望用户在设置字符串之前必须等待每个图标下载。
我有一个ListView布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
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_width="50dp"
android:layout_height="50dp"
android:contentDescription="@string/loading"
android:scaleType="fitXY"
android:src="@drawable/image" >
</ImageView>
<TextView
android:id="@+id/label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
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_width="match_parent"
android:layout_height="match_parent"
android:background="@color/color_white"
android:orientation="vertical" >
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
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);
}
}
你能告诉我我必须适应哪些功能吗? 谢谢!
答案 0 :(得分:2)
最简单的方法是将图片下载到某个Collection
,然后通过调用notifyDatasetChanged
上的Adapter
,在下载完成后更新列表。
在我们开始之前 - 我不知道您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)使用{{更新ListView
1}}。如果您的notifyDatasetChanged
是它自己的类,您可以将图像添加到回调中的碰撞中,并从那里更新列表。
对于AsyncTask
,如果您使用内置于collection
的android,则更容易,但您可以使用LruCache
或其他内容。只是取决于您的实施。
答案 1 :(得分:1)
首先,我建议将ArticleAdapter
的参考文献提供给AsyncTask
然后在Bitmap
中创建一个ArticleAdapter
数组或地图,并为ArticleAdapter创建一个add(Bitmap bmp)
方法,该方法将位图对象放入数组/地图中。
由于您在AsyncTask
中有引用,因此您可以使用下载的图标onPostExecute()
来调用 Bitma
方法中的add()方法。
然后,您可以调用ArticleAdapter
的{{1}},以便刷新其视图。
当然,如果已经下载了给定密钥的位图,则适配器的notifyDataSetChanged()
应检查其位图数组/映射。如果它的引用为null,则放一个占位符,如果已经下载,则放置由asynctask放入数组/映射中的位图。
答案 2 :(得分:1)
在getView()中,您应该开始一个新任务来下载该列表项的图像。将要填充的ImageView的引用传递给AsyncTask,然后将该ImageView的源设置为onPostExecute()中下载的位图(图标)。
这确实有点复杂,因为您必须处理由ListView回收的视图(通过取消下载图像的任务)。我喜欢使用这个库来下载和缓存图像:http://square.github.io/picasso/
答案 3 :(得分:0)
这个答案很晚,但可能对其他人有帮助。
在您的代码中,如果您的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);
}
}
}