[英]RecyclerView.Adapter return null object reference inside Fragment with viewPager
我正在嘗試使用 mvvm 架構創建具有視圖尋呼機的頁面。
所以我想要做的是使用可觀察的方法在第一個選項卡的片段內顯示 Recycler 視圖。
但是當我嘗試將內容設置為片段內的適配器時,我得到了
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);
}
所以在我的 Fragment 里面
@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
所以有人知道為什么我在onCreateView
內部初始化后調用FoodListAdapter
時得到空值?
謝謝你的幫助!
日志告訴我們什么?
D/食物尋呼機:獲取物品
調用FragmentStatePagerAdapter.getItem(int position)
以顯示FoodListFragment
。 這通常意味着Fragment
將被添加到屏幕上,因此接下來應該調用它的onCreateView()
。 實際情況是這樣的:
D/食物清單:創建視圖
另一方面,我們有一個Observer
來監聽數據變化。 每次觸發時,都會調用startFoodListFragment()
:
D/startFoodListFragment: yolo
在此方法中,將創建FoodListFragment
一個新實例。 您嘗試通過調用setFoodList()
將新數據傳遞給它
D/食物清單片段:setFoodlist
但是由於這個新實例不會被附加到屏幕上,它的onCreateView()
還沒有被調用。 所以它的適配器還沒有被實例化。 這就是應用程序崩潰的原因:
D/AndroidRuntime:關閉虛擬機 E/AndroidRuntime:致命異常:main
你能做什么?
您應該將數據傳遞到FoodListFragment
的正確實例中。 或者簡單地在FoodListFragment
注冊Observer
。 Fragment
和Activity
一樣是 Lifecycle Owner,所以我認為這種方法最適合您。
在您的活動中,您有這個方法startFoodListFragment()
,它創建一個片段並在其上調用setFoodList()
方法,該方法在內部將數據設置為適配器。
由於適配器實例是在onCreateView()
生命周期方法上創建的,因此在創建對象時不會初始化適配器。 所以那時它將為 null 這就是它拋出NullPointerException
的原因。 確保你訪問adapter的時候,一定是在onCreateView()
方法執行之后,這樣你就再也不會得到NPE
了!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.