簡體   English   中英

RecyclerView.Adapter 使用 viewPager 在 Fragment 中返回空對象引用

[英]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 FragmentActivity一樣是 Lifecycle Owner,所以我認為這種方法最適合您。

在您的活動中,您有這個方法startFoodListFragment() ,它創建一個片段並在其上調用setFoodList()方法,該方法在內部將數據設置為適配器。

由於適配器實例是在onCreateView()生命周期方法上創建的,因此在創建對象時不會初始化適配器。 所以那時它將為 null 這就是它拋出NullPointerException的原因。 確保你訪問adapter的時候,一定是在onCreateView()方法執行之后,這樣你就再也不會得到NPE了!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM