Android ListActivity:每次屏幕旋转后都会调用onCreate,选中的项目会重置,但视觉上仍保持选中状态
Android ListActivity: onCreate is called every time after screen rotation, selected item resets, but visually remains checked
如果屏幕不旋转,包含一个 TextView
和一个 ListView
对象的简单 ListActivity
工作正常。
问题描述。当运行第一次使用该应用程序时,TextView myText
显示-1
。有用。当点击不同的item时myText
sets/shows被选中的item id(或position)的值。所以,它也有效。在某个时刻,例如当项目 Two
被选中并且 myText
显示 2
我旋转屏幕并且 myText
变成 -1
(因为 onCreate
再次触发),所以这意味着 ListView myList
清除选择,但项目 Two
仍然保持选中状态(绘制为选中的 RadioButton)。有什么问题? (P.S。同样的事情发生在 GridView 上)。
这是我的源代码:
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));
}
}
发生配置更改时,将重新创建所有活动以确保使用正确的资源。
一种保留您需要的状态的方法是覆盖 onSaveInstanceState()
将您想要的所有数据放入提供的 Bundle
参数。然后,当重新创建 activity 时,您可以从 onCreate()
.
中提供的 Bundle
参数中提取保存的值
只需保存所选列表元素的索引,然后在重新创建时将其重新设置。
试试这个
<activity
android:name=".TestActivity"
android:label="@string/title_activity_test"
android:theme="@style/AppTheme"
android:configChanges="orientation|keyboardHidden|screenSize"/>
保存实例是更复杂的过程,@danail-alexiev 是正确的,在某些情况下您手动保存数据而不是恢复它。
但为什么 Checkbox 保持选中状态?简而言之,这是因为它有自己的 onSaveInstanceState
实现来处理它。并且有一些魔法调用它并将此 Parcelable 数据映射到视图 ID。你可以做简单的实验,创建一个空的应用程序,在布局中添加 EditText,没有 id - 运行 它,放一些文本,改变方向,boom - 数据丢失。然后用 id.
重试
您可以在这里找到很好的解释:Saving instance state
如果屏幕不旋转,包含一个 TextView
和一个 ListView
对象的简单 ListActivity
工作正常。
问题描述。当运行第一次使用该应用程序时,TextView myText
显示-1
。有用。当点击不同的item时myText
sets/shows被选中的item id(或position)的值。所以,它也有效。在某个时刻,例如当项目 Two
被选中并且 myText
显示 2
我旋转屏幕并且 myText
变成 -1
(因为 onCreate
再次触发),所以这意味着 ListView myList
清除选择,但项目 Two
仍然保持选中状态(绘制为选中的 RadioButton)。有什么问题? (P.S。同样的事情发生在 GridView 上)。
这是我的源代码:
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));
}
}
发生配置更改时,将重新创建所有活动以确保使用正确的资源。
一种保留您需要的状态的方法是覆盖 onSaveInstanceState()
将您想要的所有数据放入提供的 Bundle
参数。然后,当重新创建 activity 时,您可以从 onCreate()
.
Bundle
参数中提取保存的值
只需保存所选列表元素的索引,然后在重新创建时将其重新设置。
试试这个
<activity
android:name=".TestActivity"
android:label="@string/title_activity_test"
android:theme="@style/AppTheme"
android:configChanges="orientation|keyboardHidden|screenSize"/>
保存实例是更复杂的过程,@danail-alexiev 是正确的,在某些情况下您手动保存数据而不是恢复它。
但为什么 Checkbox 保持选中状态?简而言之,这是因为它有自己的 onSaveInstanceState
实现来处理它。并且有一些魔法调用它并将此 Parcelable 数据映射到视图 ID。你可以做简单的实验,创建一个空的应用程序,在布局中添加 EditText,没有 id - 运行 它,放一些文本,改变方向,boom - 数据丢失。然后用 id.
您可以在这里找到很好的解释:Saving instance state