0

I have a MainActivity inside I create ViewPager withFragments. I am using savedInstanceState to store values to set TextView after orientation changed. I also want to change value e.g. using button in MainActivity. Button works properly, but if I change the orientation then Button cannot set TextView in Fragment because TextView is now null.

MyFragment

public class MyFragment extends Fragment {

    private TextView textView;
    private String info;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.item_weather, container, false);
        textView = view.findViewById(R.id.text_view);
        Bundle bundle = getArguments();
        info = bundle.getString("info");
        setInfo(info);
        return view;

    }

    public void setInfo(String info) {
        this.info = info;
        textView.setText(info); //here is the error
    }
}

In MainActivity.java in OnCreate

myFragment = new MyFragment();
viewPager = findViewById(R.id.viewpager);
viewPager.setOffscreenPageLimit(10);

List<Fragment> fragments = new ArrayList<>();
fragments.add(myFragment);

pagerAdapter = new MyPageAdapter(getSupportFragmentManager(), fragments);
viewPager.setAdapter(pagerAdapter);

MyPagerAdapter looks like this:

public class MyPageAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> fragments;

    public MyPageAdapter(FragmentManager fm, List<Fragment> fragments) {
        super(fm);
        this.fragments = fragments;
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }
}

As I said everything works, but after orientation chage if I use Button I got an error:

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

Any ideas how to solve this?

edit: full error

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.app.myapp, PID: 15400
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
        at com.example.app.myapp.fragments.myFragment.setInfo(myFragment.java:53)
        at com.example.app.myapp.MainActivity.onOptionsItemSelected(MainActivity.java:195)
        at android.app.Activity.onMenuItemSelected(Activity.java:3543)
        at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:407)
        at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
        at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
        at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
        at android.support.v7.app.ToolbarActionBar$2.onMenuItemClick(ToolbarActionBar.java:63)
        at android.support.v7.widget.Toolbar$1.onMenuItemClick(Toolbar.java:203)
        at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:780)
        at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
        at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
        at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
        at android.support.v7.view.menu.MenuPopup.onItemClick(MenuPopup.java:127)
        at android.widget.AdapterView.performItemClick(AdapterView.java:318)
        at android.widget.AbsListView.performItemClick(AbsListView.java:1159)
        at android.widget.AbsListView$PerformClick.run(AbsListView.java:3136)
        at android.widget.AbsListView$3.run(AbsListView.java:4052)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
mcfb
  • 33
  • 8
  • Do you call setInfo from anywhere else? What is the complete stack trace? – EpicPandaForce May 26 '19 at 13:09
  • I call it from MainActivity like ```myFragment.setInfo("something")``` – mcfb May 26 '19 at 13:12
  • I added full error – mcfb May 26 '19 at 13:17
  • That's very interesting, your bug is actually in MainActivity. Possibly the way you initialize the fragment. And so onOptionsItemSelected breaks – EpicPandaForce May 26 '19 at 13:19
  • I debugged it and it seems that after rotation ```TextView``` is not null. However if setInfo tries to set ```TextView``` throws error – mcfb May 26 '19 at 13:24
  • You must add the code for MainActivity or no one will know how to fix your problem – EpicPandaForce May 26 '19 at 14:06
  • Although at a second glance, it's probably caused by https://stackoverflow.com/questions/55753099/app-crash-after-activity-has-been-killed-in-background/55754360#55754360 (although the same thing happening with FragmentStatePagerAdapter) – EpicPandaForce May 26 '19 at 14:07
  • Link to your post is good path to solve this. There are actually two different fragments. If i make ```MyFragment``` static in ```MainActivity``` it is working. – mcfb May 26 '19 at 14:29
  • Don't make it static, because then it will break from this: https://stackoverflow.com/questions/49046773/singleton-object-becomes-null-after-app-is-resumed/49107399#49107399 – EpicPandaForce May 26 '19 at 15:02
  • Ok, I try to initialize ```Fragments``` in ```MyPagerAdapter``` but I got error on app startup. Added it to main post. – mcfb May 26 '19 at 15:40

2 Answers2

0

Into the fragment try to initialize the textView in the on the onViewCreated method:


@Override
public View onViewCreated(view: View, savedInstanceState: Bundle) {

   // Your initialization code here

} 
  • I initialize ```TextView``` in ```onViewCreated``` but the problem is I have two different fragments created after rotation changed. – mcfb May 26 '19 at 15:42
0

Solution:

Ok, EpicPandaForce thanks for hints.

To solve this i used in MainActivity

@Override
    protected void onResume() {
        super.onResume();
        viewPager.setAdapter(pagerAdapter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        viewPager.setAdapter(null);
    }
mcfb
  • 33
  • 8
  • That doesn't sound like it will solve a crash you would most likely get if you do https://stackoverflow.com/questions/49046773/singleton-object-becomes-null-after-app-is-resumed/49107399#49107399 – EpicPandaForce May 26 '19 at 17:04
  • But before initializing fragments I check if fragments are null in MainActivity, so I do not create too many fragments, am I right? – mcfb May 26 '19 at 17:24
  • The question isn't whether you create too many, but if when the system recreates them then you still talk to the right instance of it. – EpicPandaForce May 26 '19 at 18:07
  • So, what is your suggestion? :) – mcfb May 26 '19 at 18:33
  • I don't remember the code for FragmentStatePagerAdapter at the moment, but for regular FragmentStatePagerAdapter, the idea is to always create a new instance of fragment inside of `getItem()`, and then get instance to the Fragment using https://stackoverflow.com/questions/54279509/how-to-get-elements-of-fragments-created-by-viewpager-in-mainactivity/54280113#54280113 – EpicPandaForce May 27 '19 at 08:04