0

I have UI displaying details of a place, including some EditTexts and an adapter from this ExpandableRecyclerView library.

The UI is updated in onCreate when my ViewModel observes a change to the place. I save the adapter in onSaveInstanceState and restore it in onRestoreInstanceState.

However once I rotate my device, the old UI state is displayed. For example, I enter some text to the EditText and expand my adapter, but after I rotate my device the old text and collapsed adapter appears. I think this is because adapter is null until onChanged is called, so my adapter method in onRestoreInstanceState is skipped, and EditTexts are re-updated to old text in onChanged.

How do I save the state of my UI?

Full code can be found here.

onCreate:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);

        viewModel = new ViewModelProvider(this).get(PlaceViewModel.class);

        Intent intent = getIntent();
        if (intent.hasExtra(EXTRA_PLACE_ID)) {
            String id = intent.getStringExtra(EXTRA_PLACE_ID);


            viewModel.getPlaceById(id).observe(this, new Observer<PlaceModel>() {
                @Override
                public void onChanged(PlaceModel placeModel) {
                    // placeModel will be null if place is deleted
                    if (placeModel != null) {
                        // update UI here
                    }
                }
            });
        }
}

onSaveInstanceState and onRestoreInstanceState:

/* To save the expand and collapse state of the adapter,
you have to explicitly call through to the adapter's
onSaveInstanceState() and onRestoreInstanceState() in the calling Activity */
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    if (adapter != null) {
        adapter.onSaveInstanceState(outState);
    }
}

@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    if (adapter != null) {
        adapter.onRestoreInstanceState(savedInstanceState);
    }
}

1 Answers1

0

One solution is just check if savedInstanceState is null, if it is don't set text of EditTexts and restore adapter state.

But I didn't carefully read the ViewModel documentation: "The ViewModel class is designed to store and manage UI-related data in a lifecycle conscious way. The ViewModel class allows data to survive configuration changes such as screen rotations."

I was asking why ViewModel is saving my old UI-related data after rotation...even though that's exactly what it's supposed to do...my mistake.