安卓,Glide在大约一秒钟内显示错误的图像

7

我正在使用Glide库从URL加载图片,这些URL来自Graph Request (Facebook)。它在RecyclerAdapter中使用。当我滚动时,每个ImageView都会在不到一秒的时间内显示错误的图片,然后才会显示正确的图片。以下是代码:

@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

    ImageView main_image = viewHolder.main_image,

    getEventCover(position, main_image);

        }

private void getEventCover(int position, final ImageView img){

        GraphRequest request = GraphRequest.newGraphPathRequest(
                AccessToken.getCurrentAccessToken(),
                event.get(position).getEventID(),
                new GraphRequest.Callback() {
                    @Override
                    public void onCompleted(GraphResponse response) {

                        JSONObject data = response.getJSONObject();

                        try {
                            JSONObject cover = data.getJSONObject("cover");
                            String source = cover.getString("source");

                            Glide.with(fragment)
                                    .load(source)
                                    .diskCacheStrategy(DiskCacheStrategy.ALL)
                                    .centerCrop()
                                    .into(img);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                }
        );

        Bundle parameters = new Bundle();
        parameters.putString("fields", "cover");
        request.setParameters(parameters);
        request.executeAsync();
}

Glide异步加载图片。如果在您的布局中有默认图片,则首先会显示该图片,然后再加载正确的图片。如果是这种情况,请尝试从布局中删除默认图片或将其替换为另一张图片。 - Rene Limon
1
谢谢回复,但我没有在布局中设置默认图像。 - Panczur
2个回答

8
您的“问题”是您正在使用的ImageView是从先前的行中回收的(这些行在滚动时消失)。因此,在onBindViewHolder中,您的ImageView已经包含了以前的图像。
此图像将显示,直到获取新图像的网络请求(GraphRequest和Glide)完成。
为避免出现问题,您必须在调用getEventCover之前清除ImageView。可以通过设置占位图像或以下方式设置透明图像来完成此操作:
main_image.setImageResource(android.R.color.transparent);

3
这还不够。在调用setImageResource之前,您还必须调用Glide.clear。否则,在极少数情况下,您会看到一个随机先前的请求完成,然后才会完成新的请求。通常这是不必要的,因为into()会做同样的事情,但在这种情况下,您是异步调用into(),因此仍然需要同步调用clear。 - Sam Judd
1
@SamJudd 兄弟,你说得没错,但是即使你所说的也不起作用,我的意思是这个库加载图像非常快,它会在显示真正的图像之前加载3-4张随机的图像。 - Harkal

4
@Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) {

    ImageView main_image = viewHolder.main_image,
    main_image.setImageURI(null);
    getEventCover(position, main_image);

        }

在准备子视图显示数据的过程中,从缓存中检索以前用于显示数据的(回收)视图以进行重用。(由于此过程跳过了初始布局膨胀和构建),因此imageView明显保留着其源。立即将源设置为null可以大大提高性能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接