所有图像都加载到ListView中的相同位置

时间:2017-01-01 14:55:30

标签: android listview android-viewholder

我在ImageView填写ListView时遇到问题 问题是所有图像都填充在同一个地方(在最底部列表项的图像视图中)。我可以看到图像在被填满时快速加载。

public class TheaterListAdapter extends ArrayAdapter<ConstantsTheaterList> implements IResult {

    private ViewHolder viewHolder;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {


        if (convertView==null){
            convertView = LayoutInflater.from(mContext).inflate(R.layout.fragment_theater_list_item, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.theater_list_item_image);
            viewHolder.textViewLatitude = (TextView) convertView.findViewById(R.id.theater_list_item_latitude);
            viewHolder.textViewLongitude = (TextView) convertView.findViewById(R.id.theater_list_item_longitude);
            viewHolder.textViewVicinity = (TextView) convertView.findViewById(R.id.theater_list_item_vicinity);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        //Picasso.with(getContext()).load(uri.toString()).into(mImageView); [WORKS FINE]

        // Using Volley to fetch image from the web.
        new VolleyService(mContext, this).volleyImageRequest(uri.toString(), 100, 100);


        String latitude = getItem(position).latitude;
        String longitude = getItem(position).longitude;
        String vicinity = getItem(position).vicinity;

        viewHolder.textViewLatitude.setText(latitude);
        viewHolder.textViewLongitude.setText(longitude);
        viewHolder.textViewVicinity.setText(vicinity);

        return convertView;
    }

    //These are the callbacks that I receive in my Volley implementation. Now, I fill the bitmap once they are available.
    @Override
    public void notifySuccess(Object response) {
        Bitmap bitmap = (Bitmap) response;
        viewHolder.imageView.setImageDrawable(bitmap);
    }

    @Override
    public void nofifyError(Object volleyError) {
        Log.e(TAG, (String)volleyError);
    }


    private static class ViewHolder{
        ImageView imageView;
        TextView textViewLatitude;
        TextView textViewLongitude;
        TextView textViewVicinity;
    }


}

我认为这必须是因为意见被回收。

但是,当我使用毕加索时,一切正常。

我该如何修复?

2 个答案:

答案 0 :(得分:2)

您遇到此问题的原因是,您没有正确使用查看持有者
你看,视图持有者的实例与每个单元格相关联。 在这里,当您调用“ Volley ”的方法来下载图片,然后通过它的回调方法,您使用“ ViewHolders ”填充 ImageView 实例,该实例以某种方式与ListView的最后一个单元格相关联。

还有一个问题,即您没有传递要下载图片的单元格实例。该实例是错误的。

您可以使用 Picasso UniversalImageLoader 。 由于这些允许您传递要下载图像的特定单元格的 imageview 的实例。
示例:

Picasso.with(this).load(“你的图片网址在这里”)。进入(ViewHolder.imageView);
就是这样。你很高兴......

答案 1 :(得分:0)

对于那里的每个人,谁还想了解为什么这不起作用,并希望以这种方式解决,这里是如何做到的:

每当您调用方法在背景中获取图像时,您都需要传递imageView的实例,以便放置此图像。

以下是我使用AsyncTask来获取图片的示例。

public class TheaterListAdapter extends ArrayAdapter<ConstantsTheaterList> 

    private ViewHolder viewHolder;

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {


        if (convertView == null) {
            convertView = LayoutInflater.from(mContext).inflate(R.layout.fragment_theater_list_item, parent, false);

            viewHolder = new ViewHolder();
            viewHolder.imageView = (ImageView) convertView.findViewById(R.id.theater_list_item_image);
            viewHolder.textViewLatitude = (TextView) convertView.findViewById(R.id.theater_list_item_latitude);
            viewHolder.textViewLongitude = (TextView) convertView.findViewById(R.id.theater_list_item_longitude);
            viewHolder.textViewVicinity = (TextView) convertView.findViewById(R.id.theater_list_item_vicinity);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }


        String key = mContext.getResources().getString(R.string.google_maps_key);
        String photoReference = getItem(position).photo_reference;
        String maxWidth = getItem(position).max_width;
        String maxHeight = getItem(position).max_height;
        String url = "https://maps.googleapis.com/maps/api/place/photo?";

        Uri uri = Uri.parse(url).buildUpon()
                .appendQueryParameter("key", key)
                .appendQueryParameter("maxwidth", maxWidth)
                .appendQueryParameter("maxheight", maxHeight)
                .appendQueryParameter("photoreference", photoReference)
                .build();

        //Picasso.with(getContext()).load(uri.toString()).into(mImageView);

        //new VolleyService(mContext, this).volleyImageRequest(uri.toString(), 100, 100);

        // Preparing input for MyAsyncTask...
        Object[]  object = new Object[2];
        object[0] = uri.toString();
        object[1] = viewHolder.imageView; // This is **important**
                                          //Pass the instance of imageview where the image is supposed to be filled.

        //Calling AsyncTask...
        MyAsyncTask myAsyncTask = new MyAsyncTask();
        myAsyncTask.execute(object);


        String latitude = getItem(position).latitude;
        String longitude = getItem(position).longitude;
        String vicinity = getItem(position).vicinity;

        viewHolder.textViewLatitude.setText(latitude);
        viewHolder.textViewLongitude.setText(longitude);
        viewHolder.textViewVicinity.setText(vicinity);

        return convertView;
    }
    private static class ViewHolder {
        ImageView imageView;
        TextView textViewLatitude;
        TextView textViewLongitude;
        TextView textViewVicinity;
    }

    private static class MyAsyncTask extends AsyncTask<Object, Void, Bitmap>{

        private String url;
        private ImageView imageView;
        @Override
        protected Bitmap doInBackground(Object... params) {

            url = (String) params[0];
            Log.v(TAG, url);
            imageView = (ImageView) params[1];

            return Utility.ImageHttp.read(url); // my method to fetch the image and return the Bitmap. 
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            imageView.setImageBitmap(bitmap);
        }
    }
}

现在你明白了,你可以用Picasso来做这件事。但重要的是要理解为什么它首先不起作用。