LowLevel
LowLevel

Reputation: 1095

Android ListActivity: onCreate is called every time after screen rotation, selected item resets, but visually remains checked

A simple ListActivity containing a TextView and a ListView objects works fine if screen is not rotating.

Problem description. When running the app for the first time, TextView myText shows -1. It works. When clicking on different items myText sets/shows the value of the selected item id (or position). So, it works as well. On a certain moment, when for example item Two is selected and myText shows 2 I rotate the screen and myText becomes -1 (because onCreate triggers again), so it means, the ListView myList clears selection, but item Two still remains selected (painted as a checked RadioButton). What's the problem? (P.S. Same thing happens to GridView).

Here is my source-code:

activity_test.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".TestActivity">

    <include layout="@layout/content_test" />

</android.support.design.widget.CoordinatorLayout>

content_test.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity">

    <TextView
        android:id="@+id/myText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <ListView
        android:id="@android:id/list"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/myText"
        android:choiceMode="singleChoice"/>
</RelativeLayout>

TestActivity.java

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class TestActivity extends ListActivity {

    static String[] items = {"Zero", "One", "Two"};

    TextView myText;
    ListView myList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        myList = (ListView) findViewById(android.R.id.list);
        setListAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_single_choice, items));

        myText = (TextView) findViewById(R.id.myListViewSelectedText);
        myText.setText(String.valueOf(myList.getSelectedItemPosition()));
    }

    @Override
    public void onListItemClick(ListView parent, View view, int position, long id) {
        myText.setText(String.valueOf(position));
    }
}

Upvotes: 0

Views: 314

Answers (3)

Nishant Dixit
Nishant Dixit

Reputation: 5522

try this one

  <activity
        android:name=".TestActivity"
        android:label="@string/title_activity_test"
        android:theme="@style/AppTheme"
        android:configChanges="orientation|keyboardHidden|screenSize"/>

Upvotes: 1

3mpty
3mpty

Reputation: 1385

Saving instance is more complicated process, @danail-alexiev is correct, in some cases you've save data manually and than restore it.

But why Checkbox stays checked? In short it's because it has own implementation of onSaveInstanceState that handles it. And there is some magic that calls it and map this Parcelable data with view id. You can do simple experiment, create empty app, in layout add EditText, without id - run it, put some text, change orientation, boom - data missing. Then retry with id.

You can find great explanation here: Saving instance state

Upvotes: 1

Danail Alexiev
Danail Alexiev

Reputation: 7772

When a configuration change occurs, all activities will be recreated to ensure that the correct resources are used.

One way to preserve the state that you need, is to override onSaveInstanceState() putting all data you want to the provided Bundle parameter. Then, when the activity gets recreated, you can extract the saved values from the provided Bundle parameter in onCreate().

Just save the index of the selected list element, and then set it back when recreating.

Upvotes: 1

Related Questions