Android开发ImageView调用setVisibility()报空指针错误求解
问题原因
你碰到的Attempt to invoke virtual method 'void android.widget.ImageView.setVisibility(int)' on a null object reference报错,核心是同名变量作用域混淆:
- 你在PostAdapter外层类单独声明了一个
public ImageView follow_btn;成员变量,这个变量从来没有被赋值,始终为null - 你在内部类ViewHolder里也声明了同名的
follow_btn变量,findViewById(R.id.follow_btn)的赋值操作只给ViewHolder内部的这个变量赋了值,外层类的同名变量完全没拿到控件实例 - 你在
onBindViewHolder里做空判断、在checkFollow()里调用setVisibility方法,操作的全是外层类那个从未赋值的null变量,自然一直检测到控件为null,运行就抛空指针。
修复方案
- 直接删掉PostAdapter外层类多余的
public ImageView follow_btn;成员变量,从根源避免同名变量混淆 - 所有对follow_btn控件的操作,都通过
onBindViewHolder方法传入的当前条目ViewHolder实例获取,不要在Adapter层持有单个控件的引用——RecyclerView的ViewHolder是复用的,外层持控件引用会导致滑动错位、内存泄漏 - 改造checkFollow方法,传入当前条目的follow_btn实例、目标用户id,避免复用时控件和数据不匹配
- 按需选择Firebase监听器类型,不需要持续监听节点变化时用单次监听减少资源占用
修正后的核心代码
onBindViewHolder 修正
@Override public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { // 直接从当前绑定的ViewHolder取控件,传入checkFollow方法 checkFollow(viewHolder.follow_btn, profileid); }
checkFollow 方法修正
// 方法参数传入当前条目的控件实例、要判断的目标用户id private void checkFollow(ImageView followBtn, String targetProfileId) { // 提前判空拦截异常 if (followBtn == null || firebaseUser == null) return; DatabaseReference reference = FirebaseDatabase.getInstance().getReference() .child("Follow").child(firebaseUser.getUid()).child("following"); // 单次监听即可满足进入页面判断状态的需求,避免持续回调占用资源 reference.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot dataSnapshot) { if (dataSnapshot.child(targetProfileId).exists()) { followBtn.setVisibility(View.INVISIBLE); } else { followBtn.setVisibility(View.VISIBLE); } } @Override public void onCancelled(@NonNull DatabaseError error) { } }); }
额外提示:如果后续需要做关注/取关操作,直接在ViewHolder里给follow_btn绑定点击事件即可,事件里拿到当前条目的profileid做对应逻辑,操作完成后再更新控件状态,不要在外层类持有控件引用。
内容的提问来源于stack exchange,提问作者Brandon T
相关产品推荐
相关产品推荐

