Home > OS >  How to access RecyclerViews from view pager2?
How to access RecyclerViews from view pager2?

Time:11-07

tabLayout and pager2 created

public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    myFragment = inflater.inflate(R.layout.fragment_home, container, false);

    tabLayout = myFragment.findViewById(R.id.tab_layout);
    pager2 = myFragment.findViewById(R.id.view_pager2);
    Button calculate = myFragment.findViewById(R.id.calculate_button);

    FragmentManager fm = getFragmentManager();
    adapter = new FragmentAdapterRecycler(fm, getLifecycle());
    pager2.setAdapter(adapter);

Located in onCreateView: If page slides, then RecyclerView fills normally when it calls fillFragement() If tab is clicked first, then RecyclerView in fillFragment() causes program to crash because of java.lang.NullPointerException:

pager2.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
        @Override
        public void onPageSelected(int position) {

            calc = (TextView) myFragment.findViewById(R.id.numDisplay);
            fillFragment(pager2.getCurrentItem());
            tabLayout.selectTab(tabLayout.getTabAt(position));
        }
    });

    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            
            pager2.setCurrentItem(tab.getPosition());
        }

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

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

fillFragment() this locates RecyclerView and fills it depending on page selected. Each page has its own RecyclerView.

public void fillFragment(int position) {

    if (position == 0 && isChosen) {
        String iterations = "Total Iterations: "   collatz.getIterationTotal();
        calc.setText(iterations);
        if (tabLoaded1 == false) {
            mRecyclerView = (RecyclerView) getView().findViewById(R.id.recycler_view);
            mRecyclerView.setHasFixedSize(false);
            mLayoutManager = new LinearLayoutManager(getActivity());

            mAdapter = new CollatzAdapter(collatz.getCollatzList());
            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setAdapter(mAdapter);
            tabLoaded1 = true;
        }
    }

    if (position == 1 && isChosen) {
        String evenTotal = "Total Even: "   collatz.getEvenTotal();
        calc.setText(evenTotal);

        if (tabLoaded2 == false) {

            mRecyclerView = (RecyclerView) myFragment.findViewById(R.id.recycler_view_even);
            mRecyclerView.setHasFixedSize(false);
            mLayoutManager = new LinearLayoutManager(getActivity());

            mAdapter = new CollatzAdapter(collatz.getEvenList());
            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setAdapter(mAdapter);
            tabLoaded2 = true;
        }
    }

    if (position == 2 && isChosen) {
        String oddTotal = "Total Odd: "   collatz.getOddTotal();
        calc.setText(oddTotal);
        if (tabLoaded3 == false) {
            mRecyclerView = (RecyclerView) myFragment.findViewById(R.id.recycler_view_odd);
            mRecyclerView.setHasFixedSize(false);
            mLayoutManager = new LinearLayoutManager(getActivity());

            mAdapter = new CollatzAdapter(collatz.getOddList());
            mRecyclerView.setLayoutManager(mLayoutManager);
            mRecyclerView.setAdapter(mAdapter);
            tabLoaded3 = true;
        }
    }
}

In summary, clicking on a tab causes a Null Object reference when fillFragment() is called. When sliding a page it works fine. This is because when clicking a tab, the fillFragment() is called first before the Pager2 item is created. When sliding, the Pager2 item is created first and then the fillFragment() is called which means the RecyclerView is created first before being accessed.

How can I fill the RecyclerView when clicking on a tab if the pageView is always created after I fill it causing a Null Object reference?

StackTrace

CodePudding user response:

You may be able to solve this with small changes to your current solution. But I advise you rethink what is responsible for what.

Because fragments follow their own lifecycle you can't guarantee that a fragment is attached at any given time.

So when you pull the RecyclerViews out of fragments that may or may not "exist" you will get null.

Fragments should be wholly responsible for their own views and no other entity should touch them.

The best solution would be to have a SharedViewModel that all 4 fragments have access to.

    // in evenFragment
    CollatzViewModel collatzViewModel;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
         collatzViewModel = new ViewModelProviders(getActivity()).get(CollatzViewModel.class);
         evenFragment = inflater.inflate(R.layout.fragment_even, container, false);
         mRecyclerView = (RecyclerView) evenFragment .findViewById(R.id.recycler_view_even);
         mRecyclerView.setHasFixedSize(false);
         mLayoutManager = new LinearLayoutManager(getActivity());
         mAdapter = new CollatzAdapter();
         mRecyclerView.setLayoutManager(mLayoutManager);
         mRecyclerView.setAdapter(mAdapter);
         collatzViewModel.getCollatz().observe(getViewLifeCycle(),(list)->{
             mAdapter.setList(list);
             mAdapter.notifyDataSetChanged();
         });
         return evenFragment;
    } 
    //in odd fragment
    CollatzViewModel collatzViewModel;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
         collatzViewModel = new ViewModelProviders(getActivity()).get(CollatzViewModel.class);
         oddFragment = inflater.inflate(R.layout.fragment_odd, container, false);
         mRecyclerView = (RecyclerView) oddFragment.findViewById(R.id.recycler_view_odd);
         mRecyclerView.setHasFixedSize(false);
         mLayoutManager = new LinearLayoutManager(getActivity());
         mAdapter = new CollatzAdapter();
         mRecyclerView.setLayoutManager(mLayoutManager);
         mRecyclerView.setAdapter(mAdapter);
         collatzViewModel.getCollatz().observe(getViewLifeCycle(),(list)->{
             mAdapter.setList(list);
             mAdapter.notifyDataSetChanged();
         });
         return oddFragment;
    }
    //in iteration fragment
    CollatzViewModel collatzViewModel;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        iterationFragment = inflater.inflate(R.layout.fragment_iteration, container, false);
         collatzViewModel = new ViewModelProviders(getActivity()).get(CollatzViewModel.class);
        mRecyclerView = (RecyclerView) iterationFragment.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(false);
        mLayoutManager = new LinearLayoutManager(getActivity());
        mAdapter = new CollatzAdapter();
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setAdapter(mAdapter);
        collatzViewModel.getCollatz().observe(getViewLifeCycle(),(list)->{
             mAdapter.setList(list);
             mAdapter.notifyDataSetChanged();
         });
        return iterationFragment;
    }
    //ViewModel class
    public class CollatzViewModel extends ViewModel{
        private MutableLiveData<List<BigInteger>> collatz = new MutableLiveData();
        public MutableLiveData<List<BigInteger>> getCollatz(){
             return collatz;
        }
    }
    //home fragment
    CollatzViewModel collatzViewModel;

    public void fillFragment(int position) {

        if (position == 0 && isChosen) {
            String iterations = "Total Iterations: "   collatz.getIterationTotal();
            calc.setText(iterations);
            if (tabLoaded1 == false) {
                collatzViewModel.getCollatz().setValue(collatz.getCollatzList())
                tabLoaded1 = true;
            }
        }
        if (position == 1 && isChosen) {
            String evenTotal = "Total Even: "   collatz.getEvenTotal();
            calc.setText(evenTotal);
            if (tabLoaded2 == false) {
                collatzViewModel.getCollatz().setValue(collatz.getEvenList())
                tabLoaded2 = true;
            }
        }
        if (position == 2 && isChosen) {
            String oddTotal = "Total Odd: "   collatz.getOddTotal();
            calc.setText(oddTotal);
            if (tabLoaded3 == false) {
                collatzViewModel.getCollatz().setValue(collatz.getOddList())
                tabLoaded3 = true;
            }
        }
    }
  • Related