33257

Layout not refreshing after orientation change

Question:

I have the following Activity definition:

<LinearLayout android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/inspectionMainLayout" xmlns:android="http://schemas.android.com/apk/res/android"> <LinearLayout android:layout_width="match_parent" android:layout_height="50dp" android:singleLine="false" android:id="@+id/breadCrumb" android:visibility="gone"> </LinearLayout> <ExpandableListView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/expandableListView" /> </LinearLayout>

Now in my code I do add buttons dynamically in breadCrumb LinearLayout:

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_inspection); LinearLayout mainLayout = (LinearLayout) findViewById(R.id.inspectionMainLayout); if (mainLayout != null) { ExpandableListView list = (ExpandableListView) findViewById(R.id.expandableListView); list.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView expandableListView, View view, int i, int i2, long l) { LinearLayout breadCrumb = (LinearLayout) findViewById(R.id.breadCrumb); Button filterButton = new Button(InspectionActivity.this); filterButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { onFilterButtonClick((Button) view); } }); filterButton.setText(item.getFormattedFilter()); breadCrumb.addView(filterButton); } } } ... }

This code works well, until I do not change the device orientation and my Activity is recreated. Although all the code is executing correctly, screen seems not being updated. Once I restore the previous orientation, all the items suddenly appear. Any idea why and how to fix it?

Thanks

EDIT:

I do think that I'm running into the same problem as describe in this post: <a href="https://stackoverflow.com/questions/10151975/android-findviewbyid-gives-me-wrong-pointer" rel="nofollow">Android: findViewById gives me wrong pointer?</a>

Any idea on how to solve this?

As requested my onRestoreInstanceState:

@Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); baseCategories = savedInstanceState.getParcelable(BASE_CATEGORIES_STATE); currentFilter = savedInstanceState.getParcelable(FILTERS_STATE); }

and on onSaveInstanceState:

@Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putParcelable(BASE_CATEGORIES_STATE, baseCategories); outState.putParcelable(FILTERS_STATE, currentFilter); }

now both of my classes do implement Parcelable interface. They are persisted and restored correctly.

Still for some resaon the call to the findViewById get's me pointed to the wrong object (not the one that is recreated).

Answer1:

You add views dynamically (on user click event). <br /> By default, android does not <em>"remember"</em> to keep these dynamic views when re-creating the activity on configuration changes, you have to handle this process yourself. <br />

Some possibilities :

<ul><li>

Avoid recreating activity on screen rotation by declaring android:configChanges="keyboardHidden|orientation|screenSize" for your activity in AndroidManifest.xml - This is highly <strong>not recommended</strong>

</li> <li>

"Remember" what views were dynamically added when re-creating activity after rotation (for example using extra flags to detect that new filter button was added and pass it via bundle in <a href="http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState%28android.os.Bundle%29" rel="nofollow">onSaveInstanceState</a>, and check in onCreate whether you need to re-create the button), or retain the whole view object as explained <a href="http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject" rel="nofollow">here</a>

</li> </ul>

One extra note : you perhaps want to specify "vertical" orientation for your breadCrumb layout, it is horizontal by default.

Answer2:

I found out why this is happening.

onSave/onRestoreInstanceState I was persisting the currentFilter class which has some custom listeners on it.

As onResume method I was doing the following:

@Override protected void onResume() { if (currentFilter == null) { currentFilter = new FilterItemList(); currentFilter.addListener(new FilterItemListListener() { @Override public void filterChanged(FilterChangedEvent e) { filterCategories(categoryRepository); } @Override public void filterAdded(FilterAddedEvent e) { FilterItem addedItem = e.getAddedItem(); baseCategories.remove(new BaseCategory("", addedItem.getSectionName())); } @Override public void filterRemoved(FilterRemovedEvent e) { FilterItem removedItem = e.getRemovedItem(); baseCategories.add(new BaseCategory("", removedItem.getSectionName())); } }); } }

The pointer to the previous instance was persisted. That's why my interface was not behaving correctly.

Now I do re-register listeners even when currentFilter is not null (it is restored) so they can point to the right instance.

Is there any pattern in handling this situations?

Thanks

Recommend

  • Set text to TextView at a particular position inside a ListView
  • setonclicklistener on another activity
  • How to give position zero of spinner a prompt value?
  • launch an installed app with my own by pressing a button
  • Android How to sum total of two different list in same fragment called with retrofit2?
  • if i take screenshot, the screen shot image show in my activity.how to hide it? [closed]
  • GPS Location not being changed android
  • Fetch facebook user Data
  • How to display image and text from Cardview in another activity onClick?
  • Deleting a single SQLite row
  • setSingleChoiceItems value doesn't stick after Activity kill
  • ShareDialog dismiss immediately
  • Android: Create a single choice dialog with disabled OK button until selected
  • how to fetch single data from server into textview in android volley?
  • How to get time from Network in Android
  • View.onClickListner not called from other class
  • Taking an image and cropping it
  • Sound sometimes remains silent when playing more sounds in a row, why?
  • RecyclerView on Click Listener Not working
  • Confusion regarding number of alarms needed to be set
  • android flash turn on/off using button while camera is running
  • Android: Simple how to stop mediaplayer after given time
  • How to Autostart an AlarmManager to start a Scheduled Activity?
  • Android SimpleAdapter wrong data-item gets associated with a list row
  • How to get respective text and image from the respective recyclerview item in floaty upon clicking a
  • Anonymous event
  • Getting the location periodically and plotting markers to map
  • android intent not work for wifi,sound,bluetooth?
  • Android Floating Window
  • Could not re-enable the KeyGaurd once disabled it
  • Error inflating class ImageButton
  • Get HTML5 validation to work with onclick?
  • jQuery Slick Slider showing some empty slides
  • Eventbus onMessageEvent not getting called
  • Javascript (MVC) load image (byte array) from database
  • Send data from edittext to listview
  • Retrofit SocketTimeoutException (and/or http 500 error) on http-POST
  • Jquery Mobile pageLoading() Method how does it work?
  • Simulate click Geckofx vb,net
  • failed to connect to specific WiFi in android programmatically