-1

I have a drawer layout which navigates between two fragments (just as it is set up when creating a new project with a drawer layout: so there is a navigation graph and general setup with AppBarConfiguration. I just removed a whole bunch of stuff so that I would end up with two fragments only).

The problem: when I navigate to the second fragment, and change the orientation of the device twice (so flip the phone landscape, then back to portrait) then I get a nullpointerException in the starting destination's onSavedInstanceState() method. I was wondering why this happens? Is there a way to pop that fragment or something, since it is not even visible? I kind of expected the navigation UI to handle this correctly, since I thought that was its purpose - but, now I feel like I might be missing something real important

Navigation graph:

<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mobile_navigation"
app:startDestination="@+id/nav_home">

<fragment
    android:id="@+id/nav_home"
    android:name="SomeNameHome"
    android:label="@string/menu_auction"
    tools:layout="@layout/fragment_auction" />

<fragment
    android:id="@+id/nav_gallery"
    android:name="SomeNameGallery"
    android:label="@string/menu_basket"
    tools:layout="@layout/fragment_basket" />

</navigation>

Then, the Home Activity:

/** Activity containing the Auction and Basket fragments. */
public class HomeActivity extends AppCompatActivity {

    private AppBarConfiguration mAppBarConfiguration;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        DrawerLayout drawer = findViewById(R.id.drawer_layout);
        NavigationView navigationView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery)
                .setDrawerLayout(drawer)
                .build();
        navigationView.setItemIconTintList(null);
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}

The problem code, in the starting destination fragment:

 @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        LinearLayoutManager m = (LinearLayoutManager) mSearchResultsList.getLayoutManager();
        outState.putInt(SAVED_INSTANCE_POSITION, m.findFirstCompletelyVisibleItemPosition() );
    }

mSearchResultList is null on the second orientation change.

Zee
  • 1,592
  • 12
  • 26
  • Hey guys! While I'm fine with being downvoted, please do give me a reason so I can improve the question? – Zee Oct 07 '19 at 12:49

1 Answers1

0

Discovered something new today:

"If you make state restorations in the onCreateView() or in the onViewCreated(), it will be lost in case of a double orientation change when the fragment is in the backstack. Actually, after the first change, the state will be saved then lost because only the onCreate() will pass. The second orientation change will then triggers the onSaveInstanceState() on a null state."

from this article: https://medium.com/@jacquesgiraudel/problem-with-restoring-fragments-from-the-backstack-945dc3f7f5a5

It goes further by advising: "if your fragment is backstack-able, make your state restorations in the onCreate()"

So, there ya go! Hopefully this will help someone else that has made the same mistake as I did!

Zee
  • 1,592
  • 12
  • 26