Android listview disappears after screen rotation
Solution 1
The ListView gets recreated when you do setContentView in the onConfigurationChanged method. You need to load the data into the ListView again. if you are binding the ListView to an adapter, you need to do it in onConfigurationChanged.
Solution 2
Use configChanges in your activity under manifest file.
<activity
...
...
android:configChanges="orientation|screenSize|keyboard">
</activity
This worked for me.
Solution 3
There are 2 things can solve your problems:
Solver A:
-
Add
android:configChanges="orientation|keyboardHidden"
in your manifest xml file. -
REMOVE
onConfigurationChanged(Configuration newConfig)
function.
Because onCreate()
is called only once every time your Activity is initialized. While your onConfigurationChanged()
reloads and inflates the new view R.layout.mylayout
with empty data => your list will not bound with data.
Solver B:
Move your data binding code which had been written in onCreate() to the overriding method onStart()
or onResume()
. I recommend that you use onStart()
for your case of data binding.
You should see the Develop page Android Activity life cycle
(Update):
Because you load your listContent
when clicking a search button on list item, so you have to maintain the data within activity to rebuild the list from it (for e.g: a string of search). Then in the onStart()
you rebuild your list from this data.
However, it is quite strange of your logic when clicking a List's item to change the whole List itself. And notice that: onListItemClick(..)
is also fired when a button on list item is clicked.
Solution 4
You must to override onSaveInstanceState
and onRestoreInstanceState
On the onSaveInstanceState
save the ListView
list on the Bundle
.
On the onRestoreInstanceState
, restore the list with the Bundle
and recreate the adapter.
private ArrayList<String> data;
@Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("d", data);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null) {
data = (ArrayList<String>) savedInstanceState.getSerializable("d");
ListViewAdapter adapter = new ListViewAdapter(this, data);
ListView listView = (ListView) findViewById(R.id.layout_listview);
listView.setAdapter(adapter);
}
super.onRestoreInstanceState(savedInstanceState);
}
Favolas
Updated on July 18, 2022Comments
-
Favolas almost 2 years
On my layout, I have some buttons tho make some choices and then one button to perform a query to a database. The result of this query is shown in a
ListView
inside this layout.The problem is if after I perform the query I rotate the screen, the
ListView
disappears and have to perform the query again.I believe that this is happening because the activity restarts. Following the suggestions here I've added to my activity in the manifest
android:configChanges="orientation|keyboardHidden"
and in my code added:@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setContentView(R.layout.mylayout); }
But this is not working.
Here is the complete code of my activity:
public class MyClass extends ListActivity implements OnClickListener, OnCheckedChangeListener { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.mylayout); // Creates the buttons and setOnClickListener and setOnCheckedChangeListener } @Override public void onClick(View v) { // Manages the buttons and their functions @Override public void onCheckedChanged(RadioGroup group, int checkedId) { // See what group in radio group is checked } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // After pressing one button, a query is made and a listview is shown. // This it to handle the user choice after he clicks an item on the listview } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); setContentView(R.layout.mylayout); } }
This is strange because I have some other activity like this:
public class AtoZ extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.atoz); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { // TODO Auto-generated method stub super.onListItemClick(l, v, position, id); } }
This also performs a query to the database, shows it on a
ListView
and then handles the user choice. If I rotate the screen,ListView
still shows.What can I do?
-
Sameer over 11 yearsWhy do you set the layout to R.layout.nutrient in the onConfigurationChanged method (instead of R.layout.mylayout as done in the onCreate method)?
-
Favolas over 11 years@Sameer Forgot to change that. Corrected
-
Sameer over 11 yearsHow do you put the data into the ListView? Do you bind it to the DB cursor?
-
Favolas over 11 years@Sameer yes.
Cursor query = baseDados.getData(1,0,null); MyAdapt cursorAdapter = new MyAdapt(this, query,0); listContent.setAdapter(cursorAdapter);
OnMyAdapt
the view is bind to the cursor -
Kamal over 11 yearsremove onConfigurationchange method if you are not changing layout. it is sufficient to write in manifiest file.
-
Favolas over 11 years@Kamal Removed and after screen rotation, listview dissapears
-
-
Favolas over 11 yearsThanks, but Wy do i have to do this in this case and in the class
AtoZ
, that it almost the same thing, I don't? -
Sameer over 11 yearsbased on your comment, you need to save the cursorAdapter as a class member probably, so it can be bound to in onConfigurationChanged.
-
Favolas over 11 yearsDone that and nothing happened. Found one strange thing. in
public void onConfigurationChanged(Configuration newConfig)
typedSystem.out.println("enter here");
It is not printed on logcat -
Favolas over 11 yearsSolver A did not work neither solver b. Put all of my code inside
onStart()
and after rotation, still the same -
Kelvin Trinh over 11 yearsDid you call
super.onListItemClick(l, v, position, id);
in your overriding methodprotected void onListItemClick(..)
? -
Kelvin Trinh over 11 yearsyou may see more for the solution at: setRetainInstance
-
Kelvin Trinh over 11 yearsHave your read this: ... For any types of configuration changes you say that you handle there, you will receive a call to your current activity's
onConfigurationChanged(Configuration)
method instead of being restarted. If a configuration change involves any that you do not handle, however, the activity will still be restarted andonConfigurationChanged(Configuration)
will not be called. From: Activity dev page -
Sameer over 11 yearsSo looks like your android:configChanges setting is not taking effect. Can you post the Manifest.xml as well?
-
Sameer over 11 yearsFound the problem. You need to add "|screenSize" to configChanges setting in Manifest. stackoverflow.com/questions/5620033/…
-
Favolas over 11 years@Sameer Sorry for the late check up but been away on vacancies. I've added "|screenSize" to configChanges setting in Manifest and now it works as expected. Imagine I have another layout for when the user rotates the screen (in layout-land). If, in portrait mode, user press the button and the query is made and the listview with the results of this query are shown, if he rotates the screen, the new layout kicks in thus now showing the listview. How can I save this listview so when the user rotates the screen it shows the listview?
-
Favolas over 11 yearsSorry for the late check up but been away on vacancies. Yes. I've called super.onListItemClick(l, v, position, id); in my overriding method protected void onListItemClick(..). Sorry but did not understand how to use setRetainInstance. Now I what to save the listview result so when the user rotates the screen and the layout-land kicks in it shows the listview that was shown in portrait mode.
-
Sameer over 11 yearsI believe you can't save the ListView object itself. The ListView will be recreated when the setContentView is done after configuration change. But when you bind the ListView to the cursor of the previously executed query, you should see all the rows you were seeing earlier.
-
Kelvin Trinh over 11 yearsCould you post your Manifiest xml, and some of your code which load the list; and post your Android SDK version?! I saw that you load the list view when a ListItem is clicked? this is quite strange way because at that time, the new list instance is replaced.
-
Favolas over 11 yearsThanks. Pasted the code that I have at pastebin.com/WyKPBhwm Thanks for all the help
-
Favolas over 11 yearsThanks Sameer. You where very helpful
-
Kelvin Trinh over 11 yearsI didn't see
android:configChanges="orientation|keyboardHidden|screenSize"
in your xml. And notice that:onListItemClick
is also fired with search button clicked because SrchBut is shown on list item. -
Favolas over 11 yearsThanks. My buttons are on top of the list content. They are always visible on the layout.The search button is not inside a list. I forgot to say but the user choices on button one, button two and radiogroup are stored on a string array. Then, when the user presses the button 3, code inside that button goes to that string array to get the search conditions. Then the query to the database is made and it's results are shown on the listview.
-
Favolas over 11 yearsI've removed adroid:config changes because if I mantain that, when the user rotates the screen, the original layout is manteined and now I want to load a new layout. If user is on portrait mode and rotates de screen, landscaped layout it's loaded and vice-versa.