-1

First, sorry if my english isn't really good !

I'm currently programming a stock management app for a small business. I currently have a view pager (with a FragmentStatePagerAdapter) regrouping different fragments, note that each fragment not "show" are already loaded in cache memory thanks to the pager.setOffscreenPageLimit(4).

I would like that when I select an object in a spinner on a fragment, it updates the other fragment by also selecting that object and then displaying the corresponding data.

I had the idea to store the rank of the object in the main activity that is common to all fragments (with getter and setter). So when an object is selected in one of the spinner we call the method setRank(); of the main to update it and the updateData(); method of each fragment that will update their date thanks to getRank();.

Main Activity :

    public int getRankObject(){ 
        return rankObjectMain; 
    }

    public void setRankObject(int newRank){
        rankObjectMain = newRank;
    }

    public void startViewPager(int num){
        tabSwitchAdapter tabSwitchAdapter = new tabSwitchAdapter(getSupportFragmentManager());

        if((!pager.isShown())) {
            pager.setAdapter(tabSwitchAdapter);
            pager.setOffscreenPageLimit(4);
            tabLayout.setupWithViewPager(pager);
        }

        Fragment fragment1 = tabSwitchAdapter.getItem(1);
        ((FragmentOne) fragment1).update();
        Fragment fragment2 = tabSwitchAdapter.getItem(2);
        ((FragmentTwo)fragment2).update();
        Fragment fragment3 = tabSwitchAdapter.getItem(3);
        ((FragmentThree)fragment3).update();

        pager.setCurrentItem(num);
    }

Fragment X :

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
                rankObject = i;
                ((MainActivity) getActivity()).setRankObject(rankObject);
                ((MainActivity) getActivity()).startViewPager(X);
            }

            @Override
            public void onNothingSelected(AdapterView<?> adapterView) {

            }
        });


 public void update(){
        rankObject = ((MainActivity) getActivity()).getRankObject();
        if(rankObject != null){
            //Update the data of the fragment    
            spinner.setSelection(rankObject);
        }
        else {
            Toast.makeText(getContext(), "The rank is null", Toast.LENGTH_SHORT).show();
        }
    }

I would have thought that this solution would work, but that it has already been a few moments that I block on it and I don't find the solution. The application crash at the moment of the method getRank(); is called

 this.rankObject = ((MainActivity)getActivity()).getRankObject();

saying that the object reference is null, I do not understand ? Each object exists well, and the rankObject of the main and of each fragment are well initialized.. Is it possible to do that this way ?

Here is the error :

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example, PID: 9641
    java.lang.NullPointerException: Attempt to invoke virtual method 'int com.example.dinovente.MainActivity.getRangProduit()' on a null object reference
        at com.example.FragmentOne.update(FragmentOne.java:201)
        at com.example.MainActivity.startViewPager(MainActivity.java:158)
        at com.example.FragmentTwo.onItemSelected(FragmentTwo.java:119)
        at android.widget.AdapterView.fireOnSelected(AdapterView.java:947)
        at android.widget.AdapterView.dispatchOnItemSelected(AdapterView.java:936)
        at android.widget.AdapterView.access$300(AdapterView.java:56)
        at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:901)
        at android.os.Handler.handleCallback(Handler.java:891)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:7470)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:958)
Diego Malone
  • 1,044
  • 9
  • 25
AnoJo
  • 1
  • Use `FragmentPagerAdapter`, and refer to https://stackoverflow.com/questions/54279509/how-to-get-elements-of-fragments-created-by-viewpager-in-mainactivity/54280113#54280113 to see how to retrieve your fragments (`getItem()` should be returning new items). – EpicPandaForce Jun 03 '19 at 16:52
  • You can apply Broadcast Receiver for this to update on other fragment class. – Dmarp Jun 03 '19 at 17:01
  • You can also use [Event Bus](https://github.com/greenrobot/EventBus) – cesarmarch Jun 03 '19 at 17:41

1 Answers1

0

The NPE happens because by calling tabSwitchAdapter.getItem(1) you are probably creating a brand new fragment that is not used by your viewpager and so is not attached to the activity(unless you are keeping references to your fragments which is not a good idea).

To communicate between fragments in one activity, as of now, the simplest way is to use the android architecture components ViewModel and LiveData. There is a detailed instruction here: ViewModel doc

ssynhtn
  • 1,307
  • 12
  • 18