You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RecyclerView第11项后图片消失问题求助

问题:RecyclerView条目超过11个时ImageView自动消失

我创建了一个包含CardView的Firebase RecyclerView,CardView内部包含ImageView和TextView。当上传图片及对应描述(TextView内容)时,ImageView和TextView均可见;若仅上传描述,则仅TextView可见。目前遇到的问题是:当RecyclerView中的条目数量超过11个时,ImageView会自动消失,仅TextView保留显示。

相关代码如下:

public class MainView extends AppCompatActivity { 
    private RecyclerView mPlacelist; 
    protected void onCreate(Bundle SavedInstanceState) { 
        super.onCreate(SavedInstanceState); 
        mPlacelist= (RecyclerView) findViewById(R.id.Place_list); 
        mPlacelist.setHasFixedSize(true); 
        LinearLayoutManager mLayoutManager=new LinearLayoutManager(MainView.this); 
        mLayoutManager.setReverseLayout(true); 
        mLayoutManager.setStackFromEnd(true); 
        mPlacelist.setLayoutManager(mLayoutManager); 
    } 

    public static class MainViewHolder extends RecyclerView.ViewHolder { 
        View mView; 
        public MainViewHolder(View itemView,int viewType) { 
            super(itemView); 
            mView = itemView; 
        } 

        public void setDescription(String description) { 
            TextView post_desc = (TextView) mView.findViewById(R.id.post_desc); 
            post_desc.setText(description); 
        } 

        public void setImage(final Context ctx, final String image) { 
            ImageView post_image = (ImageView) mView.findViewById(R.id.post_image); 
            //If image exist 
            if (image != null) { 
                Picasso.with(ctx).load(image).fit().centerInside().into(post_image); 
            } else if (image == null) { 
                //no image then imageview invisible 
                Picasso.with(ctx).cancelRequest(post_image); 
                post_image.setVisibility(View.INVISIBLE); 
                post_image.setVisibility(View.GONE); 
            } 
        } 
    } 

    final FirebaseRecyclerAdapter<MainBlogView, MainView.MainViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<MainBlogView, MainView.MainViewHolder>( 
            MainBlogView.class, 
            R.layout.recyclerplace, 
            MainView.MainViewHolder.class, 
            databaseReference 
    ) { 
        @Override 
        protected void populateViewHolder(final MainView.MainViewHolder viewHolder, MainBlogView model, int position) { 
            viewHolder.setDescription(model.getDescription()); 
            viewHolder.setImage(getApplicationContext(), model.getImage()); 
            viewHolder.setTimestamp(model.getTimestamp()); 
        } 

        @Override 
        public int getItemViewType(int position) { 
            return super.getItemViewType(position); 
        } 
    }; 
    firebaseRecyclerAdapter.notifyDataSetChanged(); 
    mPlacelist.setAdapter(firebaseRecyclerAdapter); 
} 
}

解决方案

这个问题的核心是RecyclerView的ViewHolder复用机制在搞鬼:当条目数量超过屏幕可显示的数量(这里是11个),滑出屏幕的ViewHolder会被复用给新进入屏幕的条目。如果之前被复用的ViewHolder对应的是“无图片”的条目,ImageView被设置成了GONE,但当复用给“有图片”的条目时,你没有重置ImageView的可见状态,导致它还是保持GONE,看起来就像图片消失了。

只需要修改setImage方法,在加载图片前先把ImageView的可见性恢复为VISIBLE,就能解决这个问题:

public void setImage(final Context ctx, final String image) {
    ImageView post_image = (ImageView) mView.findViewById(R.id.post_image);
    // 先取消之前的请求,避免图片加载混乱
    Picasso.with(ctx).cancelRequest(post_image);
    
    if (image != null) {
        // 有图片时,先恢复ImageView的可见性
        post_image.setVisibility(View.VISIBLE);
        Picasso.with(ctx).load(image).fit().centerInside().into(post_image);
    } else {
        // 无图片时,隐藏ImageView
        post_image.setVisibility(View.GONE);
        // 清空ImageView内容,避免复用残留旧图片
        post_image.setImageDrawable(null);
    }
}

关键修改点说明:

  1. 恢复可见性:在加载图片前设置post_image.setVisibility(View.VISIBLE),确保复用的ViewHolder能正确显示图片。
  2. 统一请求取消:把cancelRequest移到判断逻辑外面,不管有没有图片都取消之前的加载请求,避免图片加载错乱。
  3. 清空ImageView内容:无图片时设置setImageDrawable(null),防止复用的ViewHolder残留之前的图片。
  4. 简化逻辑:image == null的判断不需要用else if,直接else即可,代码更简洁。

另外,你可以优化ViewHolder的性能,提前初始化控件引用(而不是每次setImage都调用findViewById):

public static class MainViewHolder extends RecyclerView.ViewHolder { 
    View mView;
    TextView post_desc;
    ImageView post_image;

    public MainViewHolder(View itemView,int viewType) { 
        super(itemView); 
        mView = itemView;
        // 提前初始化控件引用,避免重复查找
        post_desc = mView.findViewById(R.id.post_desc);
        post_image = mView.findViewById(R.id.post_image);
    } 

    public void setDescription(String description) { 
        post_desc.setText(description); 
    } 

    public void setImage(final Context ctx, final String image) { 
        Picasso.with(ctx).cancelRequest(post_image);
        
        if (image != null) {
            post_image.setVisibility(View.VISIBLE);
            Picasso.with(ctx).load(image).fit().centerInside().into(post_image);
        } else {
            post_image.setVisibility(View.GONE);
            post_image.setImageDrawable(null);
        } 
    } 
}

这样修改后,不管RecyclerView有多少条目,ImageView的显示状态都会根据当前条目的数据正确切换,不会再出现莫名消失的问题。

内容的提问来源于stack exchange,提问作者yaha kaha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:18:37