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
相关产品推荐
相关产品推荐

