【问题标题】:Picasso refreshing images in ListView each time I scroll每次滚动时,毕加索都会在 ListView 中刷新图像
【发布时间】:2015-06-09 17:00:28
【问题描述】:

我有一个 ListView,每次我上下滚动时都会刷新图像

我正在从我提供给毕加索的 JSON 中挑选图片网址。

我正在使用 Picasso 加载图像。

所有图像的总大小为 516kb,知道这一点,我不认为这是缓存问题,因为图像大小实际上很小。

老实说,我已经在 S.O 上研究过这个问题,但还没有看到任何好的解决方案。

也许这个问题与毕加索无关,也许我的实现实际上是错误的。请我需要更多这方面的知识。

这是我下面的代码。

public class ImageAdapter extends ArrayAdapter<Genres> {

    ArrayList<Genres> movieList;
    TextView movietitle, moviecategory;

    LayoutInflater vi;
    int Resource;
    ViewHolder holder;

    private Context mContext;

    public ImageAdapter(Context context, int resource, ArrayList<Genres> objects) {
        super(context, resource, objects);
        vi = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Resource = resource;
        movieList = objects;
        mContext = context;
    }

    // create a new ImageView for each item referenced by the Adapter
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ImageView imageView;
        if (v == null) {
            holder = new ViewHolder();
            v = vi.inflate(Resource, null);

            holder.imageview = (ImageView) v.findViewById(R.id.movieimage);

            LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(96, 128);
            holder.imageview.setLayoutParams(layoutParams);
            holder.imageview.setScaleType(ImageView.ScaleType.CENTER_CROP);
            holder.imageview.setPadding(4, 4, 4, 4);
            holder.imageview.setAdjustViewBounds(true);

            holder.movietitle = (TextView) v.findViewById(R.id.movietitle);
            holder.moviecategory = (TextView) v.findViewById(R.id.moviecategory);

            v.setTag(holder);

        } else {
            holder = (ViewHolder) v.getTag();
        }

        Picasso.with(mContext)
        .load(movieList.get(position).getImage())
        .noFade()
        .into(holder.imageview);

        holder.movietitle.setText(movieList.get(position).getMoviename());
        holder.moviecategory.setText(movieList.get(position).getCategory());

        return v;
    }

    static class ViewHolder {
        public ImageView imageview;
        public TextView movietitle;
        public TextView moviecategory;
    }

}

【问题讨论】:

  • 如果您认为您的图像没有被缓存,您可以在 Picasso 实例上设置setIndicatorsEnabled(true) 以查看它是否从 memoryCache 加载。 Picasso
  • “刷新”到底是什么意思?
  • @david.mihola 刷新是指图像在我滚动离开它们时消失,图像不在当前窗口中,当我向上滚动时,它会消失
  • 每次滚动时它总是尝试再次请求图像
  • @mrtn 当我使用 setIndicators 和 setLogging 时,我发现图像实际上正在被缓存。它显示我“从记忆中完成”

标签: android listview picasso


【解决方案1】:

我认为您在这里遇到的问题是您将持有人对象设为适配器类的实例变量,因此实际上您只有一个视图持有人。

尝试删除你的实例变量声明

LayoutInflater vi;
int Resource;
ViewHolder holder;    // remove or comment out this line 

private Context mContext;

然后创建新的视图持有者和getTag()返回的持有者

局部变量。

所以这两个变化:

第一:

if (v == null) {
   // holder = new ViewHolder();
   ViewHolder holder = new ViewHolder();  // replace above commented line with this line
   v = vi.inflate(Resource, null);

然后在你的 else 子句中:

    } else {
    //    holder = (ViewHolder) v.getTag();
          ViewHolder holder = (ViewHolder) v.getTag(); // replace above commented line with this one.
    }

现在布局存储的持有者将是不同的视图,而不是您当前拥有的唯一一个。

作为参考,这里是我与毕加索一起使用的适配器。有几个不同之处,但我认为主要是您对 viewHolder 变量使用单个实例变量。

public class FollowedUsersListAdapter extends ArrayAdapter<UserListItem> {
    private final Context context;
    private final ArrayList<UserListItem> values;

    public FollowedUsersListAdapter(Context context, ArrayList<UserListItem> values) {
        super(context, R.layout.row_layout, values);
        this.context = context;
        this.values = values;
    }

    static class ViewHolder {
        public TextView userNameView;
        public TextView lastPostView;
        public TextView postedTimeAgoView;
        public ImageView imageView;
    }

    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        View followedUserView = convertView;
        if (followedUserView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            followedUserView = inflater.inflate(R.layout.followed_user_item_layout, parent, false);
            ViewHolder viewHolder = new ViewHolder();
            viewHolder.userNameView = (TextView) followedUserView.findViewById(R.id.user_name);
            viewHolder.lastPostView = (TextView) followedUserView.findViewById(R.id.last_post);
            viewHolder.postedTimeAgoView = (TextView) followedUserView.findViewById(R.id.posted_time_ago);
            viewHolder.imageView = (ImageView) followedUserView.findViewById(R.id.user_icon);
            followedUserView.setTag(viewHolder);
        }

        ViewHolder holder = (ViewHolder) followedUserView.getTag();
        holder.userNameView.setText(values.get(position).getName());
        holder.lastPostView.setText(values.get(position).getLastMicropost());
        holder.postedTimeAgoView.setText(values.get(position).getPostedTimeAgo());
        ImageView imageView = holder.imageView;
        String gravatarURL = "http://www.gravatar.com/avatar/"
                + values.get(position).getGravatarId();
        Picasso.with(context).load(gravatarURL).into(imageView);


        return followedUserView;
    }

}

【讨论】:

  • 感谢您的回答,虽然我试过了,但并没有好转。后来我使用 Picasso .resize(96, 128) 直接调整我的图像大小,而不是在布局参数中设置它有更好的优化,现在问题已经解决了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-26
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
相关资源
最近更新 更多