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

Fragment中RecyclerView不更新,调用notifyDataSetChanged时Adapter为空

销售APP购物车RecyclerView刷新空指针问题排查

问题背景

开发一款分三阶段的销售APP,采用单Activity+Tab布局+3个Fragment架构,流程为用户添加商品→购物车结算→打印收据。目前第一阶段已完成,购物车页面使用RecyclerView:

  • 初始化时能正常加载列表
  • 添加商品后切换到购物车Tab,列表无更新,但打印功能显示商品已成功添加
  • 尝试调用notifyDataSetChanged更新时触发空指针异常

错误信息

java.lang.NullPointerException: Attempt to invoke virtual method 'void app.project.jsml_sales_app.adapters.CartItemAdapter.updateCartList(java.util.ArrayList)' on a null object reference
    at app.project.jsml_sales_app.activities.fragments.CartFragment.loadItemsInCart(CartFragment.java:128)
    at app.project.jsml_sales_app.activities.NewSaleActivity$1.onTabSelected(NewSaleActivity.java:78)
    at com.google.android.material.tabs.TabLayout.dispatchTabSelected(TabLayout.java:1993)
    at com.google.android.material.tabs.TabLayout.selectTab(TabLayout.java:1986)

错误原因

在NewSaleActivity的Tab选中监听逻辑中,每次选中购物车Tab时新建了一个CartFragment实例,而非获取ViewPager中已经加载的现有实例。这个新创建的Fragment还未执行onViewCreated方法,cartItemAdapter未完成初始化,此时调用loadItemsInCart()必然触发空指针。

解决方案

1. 修改NewSaleActivity的Tab选中监听逻辑

获取ViewPager适配器中已存在的CartFragment实例,而非新建:

tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        if(tab.getPosition() == 1) {
            // 获取ViewPager中已加载的CartFragment实例
            CartFragment cartFragment = (CartFragment) sectionsPagerAdapter.getItem(tab.getPosition());
            // 确保Fragment已附加到Activity且视图已创建
            if(cartFragment.isAdded() && cartFragment.getView() != null) {
                cartFragment.loadItemsInCart();
            }
        }
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {}

    @Override
    public void onTabReselected(TabLayout.Tab tab) {}
});

2. 给CartFragment的刷新方法增加空安全判断

避免因适配器未初始化导致的空指针:

public void loadItemsInCart() {
    ArrayList<CartItem> cartList = Paper.book().read("cartItems", new ArrayList<CartItem>());
    for(CartItem cartItem : cartList) {
        Log.d("cartItem", cartItem.getItemName());
    }

    // 增加适配器非空判断
    if(cartItemAdapter != null) {
        cartItemAdapter.updateCartList(cartList);
        Log.d("loadItemsInCart", "Load Items In Cart is triggered");
    }
}

3. 可选优化:让SectionsPagerAdapter保存Fragment引用

如果你的SectionsPagerAdapter的getItem()方法每次都返回新Fragment实例,建议修改适配器,保存已创建的Fragment列表,确保获取到的是同一个实例:

public class SectionsPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> fragmentList = new ArrayList<>();

    public SectionsPagerAdapter(Context context, FragmentManager fm) {
        super(fm);
        // 初始化三个Fragment
        fragmentList.add(AddItemFragment.newInstance());
        fragmentList.add(CartFragment.newInstance());
        fragmentList.add(ReceiptFragment.newInstance());
    }

    @Override
    public Fragment getItem(int position) {
        return fragmentList.get(position);
    }

    @Override
    public int getCount() {
        return fragmentList.size();
    }

    // 提供方法获取指定位置的Fragment
    public Fragment getFragment(int position) {
        return fragmentList.get(position);
    }
}

之后在Activity中调用sectionsPagerAdapter.getFragment(tab.getPosition())来获取CartFragment实例。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:25:53