1

如何在此布局中设置图像?

列表条目

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

加载缩略图异步任务:

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

你能告诉我我必须适应哪些功能才能实现这一目标吗?谢谢!

4

4 回答 4

2

最简单的方法是将您的图像下载到某些文件中Collection,然后在下载完成时通过调用notifyDatasetChanged.Adapter

在我们开始之前 - 我不知道你在哪里AsyncTask。如果它是一个单独的类,您需要使用 anInterface来设置对您开始它的位置的回调。如果它是您的内部类,您Adaper可以在本地执行此操作。

你要做的是设置你Adapter的(1)检查你想要的图像是否可用(2)如果没有下载图像并将其添加到集合中(3)当图像下载时刷新列表(或下载所有图像时取决于此列表的长度)。

当您为特定列表项设置内容时,这一切都会发生

if(logo != null){
    if(imageCollection.contains(key){
        logo.setImageBitmap(imageCollection.get(key));
    } else {
        thumbnailDownloader.execute;
    }
} 

如果您是AsyncTask适配器中的内部类,那么onPostExecute您将(1)将图像添加到此集合(2)更新ListViewusing notifyDatasetChanged. 如果你AsyncTask是它自己的类,你可以将图像添加到回调中的集合中,并从那里更新列表。

因为collection如果你使用LruCache内置的 android 会更容易,但你可以使用 aHashMap或其他东西。仅取决于您的实施。

于 2013-08-27T13:19:40.360 回答
1

首先,我建议ArticleAdapterAsyncTask.
然后在 中创建一个Bitmap数组或映射,并为 ArticleAdapterArticleAdapter创建一个方法,该方法将位图对象放入数组/映射中。 因为在 中有引用,所以可以在方法中调用 add() 方法,用下载的图标p。 然后你可以调用's ,所以它可以刷新它的视图。 当然,如果给定键的位图已经下载,您的适配器应该检查它的位图数组/映射。如果它的引用为空,则放置一个占位符,如果已经下载,则放置由异步任务放入数组/映射中的位图。add(Bitmap bmp)
AsyncTaskonPostExecute()Bitma
ArticleAdapternotifyDataSetChanged()

getView

于 2013-08-27T13:18:43.373 回答
1

在 getView() 中,您应该启动一个新任务来下载该列表项的图像。将要填充的 ImageView 的引用传递给 AsyncTask,然后在 onPostExecute() 中将该 ImageView 的源设置为下载的位图(图标)。

这确实有点复杂,因为您将不得不处理由 ListView 回收的视图(通过取消下载图像的任务)。我喜欢使用这个库来下载和缓存图片:http ://square.github.io/picasso/

于 2013-08-27T13:21:01.010 回答
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);
            }
        }
    }
于 2017-07-14T17:19:49.683 回答