-1

I am new to using fragments, I am trying to execute a fragment method from my main activity, the method compares a textview and then deletes cookies and loads a website.

This is what I have:

In MainActivity:

NavigatorFragment navigator = new NavigatorFragment();
navigator.refresh();

In Fragment:

public void refresh(){
    if (!textView.getText().toString().equals("Click HERE")){
        cookieManager.removeAllCookie();
        cookieManager.removeSessionCookie();
        myWebView.loadUrl(URL);
    }
}

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

EDIT

Sorry but forget to mention that although the fragment is started the same thing happens, I previously used this code to prevent my fragments from restarting: link So when I press item4 of my BottomNavigationView it opens the fragment, in onCreateView:

textView = root.findViewById(R.id.textView);

when I press it again (without having changed fragment) is when I want the method to be executed

I repeat, when I press item 4 BottomNavigationView for the first time, it opens Fragment 4 and loads its elements, when I press item 4 a second time (without having changed the fragment) that's when I want the method to run

Main Activity:

public class MainActivity extends AppCompatActivity {

/*
Fragment MyFragment;
private NavController navController;
 */
NavigatorFragment navigator = new NavigatorFragment();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.nav_view);
    navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

    replace_fragment(new HomeFragment());
}

private void replace_fragment(Fragment fragment) {

    String tag = fragment.getClass().getSimpleName();
    FragmentTransaction tr = getSupportFragmentManager().beginTransaction();

    Fragment curFrag = getSupportFragmentManager().getPrimaryNavigationFragment();
    Fragment cacheFrag = getSupportFragmentManager().findFragmentByTag(tag);

    if (curFrag != null)
        tr.hide(curFrag);

    if (cacheFrag == null) {
        tr.add(R.id.nav_host_fragment, fragment, tag);
    } else {
        tr.show(cacheFrag);
        fragment = cacheFrag;
    }

    tr.setPrimaryNavigationFragment(fragment);
    tr.commit();

}

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
        = new BottomNavigationView.OnNavigationItemSelectedListener() {

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()) {
            case R.id.navigation_home:
                replace_fragment(new HomeFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_schedule:
                replace_fragment(new ScheduleFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_calculators:
                replace_fragment(new CalculatorsFragment());
                if (!getSupportActionBar().isShowing()){
                    showBar();
                }
                return true;

            case R.id.navigation_navigator:
                replace_fragment(new NavigatorFragment());
                if (!getSupportActionBar().isShowing()){
                    navigator.refresh();//**************PROBLEM HERE******************************************
                }
                hideBar();
                return true;
        }
        return false;
    }
};



public void hideBar(){
    if (Build.VERSION.SDK_INT >= 19) {
        // Call some material design APIs here
        Objects.requireNonNull(getSupportActionBar()).hide();
    }
    else {
        // Implement this feature without material design
        getSupportActionBar().hide();
    }
}

public void showBar(){
    if (Build.VERSION.SDK_INT >= 19) {
        // Call some material design APIs here
        Objects.requireNonNull(getSupportActionBar()).show();
    }
    else {
        // Implement this feature without material design
        getSupportActionBar().show();
    }
}

}

**the refresh method works if run from the fragment code

JP711
  • 533
  • 6
  • 15
  • Can you show how `textView` is (supposed to be) initialized? There's not enough here to debug currently. – Ryan M Jul 01 '20 at 02:52
  • Done, I updated the question I hope you can help me, thanks @RyanM – JP711 Jul 01 '20 at 03:43
  • 1
    I generally agree with Zain's answer. You may also have the problem that you're not setting `navigator` in `replace_fragment`, so you're using a Fragment that has not been started instead of one that has. – Ryan M Jul 01 '20 at 03:49
  • I thank you very much, I will continue testing, I hope to solve it – JP711 Jul 01 '20 at 03:54

1 Answers1

1

When instantiating a fragment instance using new NavigatorFragment() that doesn't involve that the fragment life cycle starts away. Meaning that the fragment isn't created, started, resumed, and shown on the screen.. So, accessing fragment's views at this moment will return NullPointerException.

So, what you need to do is to have a placeholder for the fragment in the activity layout, and start fragment transaction by adding or replacing fragments in this placeholder, which makes the fragment passes by its all life cycle callback methods, and to give it a chance to create its view (layout) on the screen within the onCreateView() lifecycle callback, where you can just allowed to access the underlying TextView or any other view in this fragment, and use their methods like in your case textView.getText() subsequently without NullPointerException.

Here you can find how to use a fragment the right way.

Zain
  • 37,492
  • 7
  • 60
  • 84
  • Thanks for answering but I think it is not that, sorry but forget to mention that although the fragment is started the same thing happens, I previously used this code to prevent my fragments from restarting: [link](https://stackoverflow.com/a/59423979/13452141) So when I press item4 of my BottomNavigationView it opens the fragment, when I press it again a second time (without having changed fragment) is when I want the method to be executed – JP711 Jul 01 '20 at 01:11