我正在尝试创建具有mvvm体系结构的视图分页器的页面。
所以我想做的是通过使用可观察的方法在第一个选项卡的片段内显示回收站视图。
但是当我尝试设置内容是片段中的适配器时,我得到了
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.xxxx.view.adapter.FoodListAdapter.setFoodList(java.util.List)' on a null object reference
我的FragmentStatePagerAdapter适配器
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
Log.d("Food Pager", "get Item");
FoodListFragment foodListFragment = new FoodListFragment();
return foodListFragment;
case 1:
RestaurantListFragment restaurantListFragment2 = new RestaurantListFragment();
return restaurantListFragment2;
case 2:
RestaurantListFragment restaurantListFragment3 = new RestaurantListFragment();
return restaurantListFragment3;
default:
return null;
}
}
我的活动
private void observeViewModel(final CategoryViewModel categoryViewModel) {
// Observe Category Data
categoryViewModel.getCategory().observe(this, new Observer<Category>() {
@Override
public void onChanged(@Nullable Category category) {
// Update UI
if (category != null) {
if (category.foods != null) {
startFoodListFragment(category.foods);
}
} else {
Log.e(TAG, "Category Data is Null");
}
}
});
}
private void startFoodListFragment(List<CategoryQuery.Food> foodList) {
Log.d("startFoodListFragment", "yolo");
FoodListFragment foodListFragment = new FoodListFragment();
foodListFragment.setFoodList(foodList);
}
所以在我的片段里面
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.d("Food LIst", "On create VIew");
View rootView = inflater.inflate(R.layout.fragment_food_list, container, false);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview_food_list);
// mLoadingIndicator = (ProgressBar) rootView.findViewById(R.id.food_list_loading_indicator);
Integer gridColumns = 2;
Float width = getScreenSize().get("width");
if (width > 600) {
gridColumns = 3;
}
// Create Pinterest Style RecyclerView
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(gridColumns, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
// Cool. it's Very easy ,but margin on my LinearLayout didn’t seem to work. So here’s a quick fix.
SpacesItemDecoration decoration = new SpacesItemDecoration(8);
mRecyclerView.addItemDecoration(decoration);
mFoodListAdapter = new FoodListAdapter(foodListAdapterOnClickHandler);
mRecyclerView.setAdapter(mFoodListAdapter);
return rootView;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (mFoodList != null) {
mFoodListAdapter.setFoodList(mFoodList);
}
}
public void setFoodList(List<CategoryQuery.Food> foodList) {
Log.d(TAG, "setFoodlist");
if (foodList != null) {
mFoodList = foodList;
mFoodListAdapter.setFoodList(mFoodList);
// mFoodListAdapter.notifyDataSetChanged();
}
}
这是我的适配器的一部分
public void setFoodList(final List<? extends CategoryQuery.Food> foodList) {
if (this.foodList == null) {
this.foodList = foodList;
notifyItemRangeInserted(0, foodList.size());
}
}
这是我得到的相关日志
D/Food Pager: get Item
D/Food LIst: On create VIew
D/startFoodListFragment: yolo
D/Food List Fragment: setFoodlist
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
然后错误继续发生
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.xxx.view.adapter.FoodListAdapter.setFoodList(java.util.List)' on a null object reference
因此,即使我在FoodListAdapter
中初始化后,在调用onCreateView
时,有人知道为什么我会为空吗?
感谢您的帮助!
答案 0 :(得分:1)
日志告诉我们什么?
D / Food Pager:获取物品
调用FragmentStatePagerAdapter.getItem(int position)
来显示FoodListFragment
。这通常意味着Fragment
将被添加到屏幕,因此其onCreateView()
应该被下一步调用。实际上是这样:
D / Food List:创建视图
另一方面,我们有一个Observer
来监听数据更改。每次触发时,startFoodListFragment()
都会被调用:
D / startFoodListFragment:yolo
在此方法中,将创建FoodListFragment
的新实例。您尝试通过调用setFoodList()
D /食物列表片段:setFoodlist
但是由于此新实例将不会附加到屏幕,因此尚未调用其onCreateView()
。因此其适配器尚未实例化。这就是应用崩溃的原因:
D / AndroidRuntime:关闭VM E / AndroidRuntime:致命异常:main
你能做什么?
您应该将数据传递到FoodListFragment
的正确实例中。或者只是在Observer
内注册FoodListFragment
。 Fragment
是生命周期所有者,就像Activity
一样,因此我认为这种方法最适合您。
答案 1 :(得分:0)
在活动中,您具有此方法dte2.Quit();
,该方法创建一个片段,并在其上调用startFoodListFragment()
方法,该方法在内部将数据设置为适配器。
由于适配器实例是通过setFoodList()
生命周期方法创建的,因此在创建对象时不会初始化适配器。因此在那时它将为null,这就是它抛出onCreateView()
的原因。确保访问适配器时,它必须在执行NullPointerException
方法之后,这样您才永远不会再得到onCreateView()
!