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

长按RecyclerView条目设置按钮可见出现空对象引用错误如何解决

报错原因
  1. 控件查找范围错误:你需要操作的btnRemove定义在activity_main布局中,但你在ViewHolder构造方法中是从RecyclerView子项布局R.layout.stock_row里执行findViewById查找,子项布局不存在该id的控件,所以btnRemove始终为null,调用setVisibility就会抛出空指针异常。
  2. 额外逻辑错误:StockAdapter构造方法中直接new MainActivity()的写法完全不符合Android规范,Activity实例必须由Android系统创建,手动new出来的实例没有绑定任何布局和上下文,完全不可用。
修复方案

第一步:修改MainActivity代码,持有按钮实例并提供调用方法

public class MainActivity extends AppCompatActivity {

    private DBHandler db;
    Button btnAddItem;
    // 新增声明移除按钮
    Button btnRemove;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RecyclerView stockView = findViewById(R.id.rvStock);
        // 找到activity_main布局里的移除按钮,初始设为不可见
        btnRemove = findViewById(R.id.btnRemove);
        btnRemove.setVisibility(View.INVISIBLE);
        
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        stockView.setLayoutManager(linearLayoutManager);
        stockView.setHasFixedSize(true);
        db = new DBHandler(this);
        ArrayList<Stock> allStock = db.getAllStock();

        if (allStock.size() > 0) {
            stockView.setVisibility(View.VISIBLE);
            StockAdapter stockAdapter = new StockAdapter(this, allStock);
            stockView.setAdapter(stockAdapter);
        }
        else {
            stockView.setVisibility(View.GONE);
            Toast.makeText(this, "No Items!", Toast.LENGTH_LONG).show();
        }

        btnAddItem = findViewById(R.id.btnAdd);
        btnAddItem.setOnClickListener(v -> {
            addNewItem();
        });
    }

    // 新增供Adapter调用的显示按钮方法
    public void showRemoveBtn() {
        btnRemove.setVisibility(View.VISIBLE);
    }

    protected void addNewItem() {
        Intent i = new Intent(MainActivity.this, AddNewItem.class);
        startActivity(i);
    }
}

第二步:修改StockAdapter代码,调整长按触发逻辑

public class StockAdapter extends RecyclerView.Adapter<StockAdapter.ViewHolder> {

    private Context context;
    private ArrayList<Stock> listStock;
    private ArrayList<Stock> mArrayList;
    private DBHandler db;
    private MainActivity mainActivity;

    StockAdapter(Context context, ArrayList<Stock> listStock) {
        this.context = context;
        this.listStock = listStock;
        this.mArrayList = listStock;
        db = new DBHandler(context);
        // 直接把传入的context强转为MainActivity实例,不需要手动new
        mainActivity = (MainActivity) context;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View stockView = inflater.inflate(R.layout.stock_row, parent, false);
        return new ViewHolder(stockView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        final Stock stock = listStock.get(position);
        holder.tvItem.setText(stock.getItem());
        holder.tvCondition.setText(stock.getCondition());
        holder.tvQuantity.setText(String.valueOf(stock.getQuantity()));
        holder.tvLocation.setText(stock.getLocation());
        holder.tvCategory.setText(stock.getCategory());
    }

    @Override
    public int getItemCount() {
        return listStock.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
        final TextView tvItem;
        final TextView tvCondition;
        final TextView tvQuantity;
        final TextView tvLocation;
        final TextView tvCategory;
        // 移除子项中不存在的btnRemove声明
        View stockView;

        ViewHolder(View stockView) {
            super(stockView);
            this.stockView = stockView;
            stockView.setOnClickListener(this);
            stockView.setOnLongClickListener(this);
            tvItem = stockView.findViewById(R.id.tvItem);
            tvCondition = stockView.findViewById(R.id.tvCondition);
            tvQuantity = stockView.findViewById(R.id.tvQuantity);
            tvLocation = stockView.findViewById(R.id.tvLocation);
            tvCategory = stockView.findViewById(R.id.tvCategory);
            // 移除从子项布局查找btnRemove的逻辑
        }

        @Override
        public void onClick(View stockView) {

        }

        @Override
        public boolean onLongClick(View stockView) {
            // 调用MainActivity暴露的方法显示按钮
            mainActivity.showRemoveBtn();
            Toast.makeText(context, "long pressed", Toast.LENGTH_SHORT).show();
            return false;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 00:06:03