java.lang.IllegalStateException 旋转设备时在 ScrollView 中
java.lang.IllegalStateException in ScrollView when rotating device
我正在使用下面称为 fragmentView 的 ScrollView 在其中托管自定义 Fragment,它通常工作正常。但是,当我将设备旋转到横向模式并返回时,应用程序崩溃并显示
java.lang.IllegalStateException: ScrollView can host only one direct child
我在单击 Spinner 项时添加片段,如下所示:
fragmentView.removeAllViews();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
ConfigureFragment fragment = new ConfigureFragment();
fragment.setReferences(MainActivity.this, (Controller) spinner.getSelectedItem());
fragmentTransaction.add(fragmentView.getId(), fragment, "");
fragmentTransaction.commit();
我使用 removeAllViews 来确保在添加任何新内容之前 ScrollView 是空的。这是我的片段的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ConfigureFragment">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="0">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="textPersonName"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/esp_channel" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarRed"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextRed"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarGreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextGreen"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarBlue"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextBlue"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/buttonRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/esp_retrieve" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/esp_connection" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="fill_vertical"
android:padding="10dp"
android:text="@string/esp_ip" />
<EditText
android:id="@+id/editTextIP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="date"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="fill_vertical"
android:padding="10dp"
android:text="@string/esp_port" />
<EditText
android:id="@+id/editTextPort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
</TableLayout>
</android.support.constraint.ConstraintLayout>
解决方案 1
使用 replace()
而不是 add()
将片段添加到容器
当Activity由于方向改变而重新启动时,Activity被创建一次,ConfigureFragment被创建两次。
原因是如果应用程序被系统杀死,系统会自动恢复 activity 和碎片。这一幕发生在super.onCreate()。因此,上面的添加片段代码将在恢复的片段之上添加一个额外的片段,从而导致当前情况。 ScrollView 不能有多个子视图!
解决方案 2
如果您在 activity 的 onCreate() 方法中添加片段,则检查 savedInstanceState 变量(Bundle 对象)。重新创建 activity 时它不是空的,然后只添加你的片段
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
ConfigureFragment fragment = new ConfigureFragment();
fragment.setReferences(MainActivity.this, (Controller) spinner.getSelectedItem());
fragmentTransaction.add(fragmentView.getId(), fragment, "");
fragmentTransaction.commit();
}
我正在使用下面称为 fragmentView 的 ScrollView 在其中托管自定义 Fragment,它通常工作正常。但是,当我将设备旋转到横向模式并返回时,应用程序崩溃并显示
java.lang.IllegalStateException: ScrollView can host only one direct child
我在单击 Spinner 项时添加片段,如下所示:
fragmentView.removeAllViews();
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
ConfigureFragment fragment = new ConfigureFragment();
fragment.setReferences(MainActivity.this, (Controller) spinner.getSelectedItem());
fragmentTransaction.add(fragmentView.getId(), fragment, "");
fragmentTransaction.commit();
我使用 removeAllViews 来确保在添加任何新内容之前 ScrollView 是空的。这是我的片段的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ConfigureFragment">
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="0">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:gravity="center"
android:inputType="textPersonName"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:text="@string/esp_channel" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarRed"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextRed"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarGreen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextGreen"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<SeekBar
android:id="@+id/seekBarBlue"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:max="@integer/esp_value_max"
android:progress="@integer/esp_value_min" />
<EditText
android:id="@+id/editTextBlue"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/buttonRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="@string/esp_retrieve" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center"
android:text="@string/esp_connection" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="fill_vertical"
android:padding="10dp"
android:text="@string/esp_ip" />
<EditText
android:id="@+id/editTextIP"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="date"
android:padding="10dp" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView4"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="fill_vertical"
android:padding="10dp"
android:text="@string/esp_port" />
<EditText
android:id="@+id/editTextPort"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:padding="10dp" />
</TableRow>
</TableLayout>
</android.support.constraint.ConstraintLayout>
解决方案 1
使用 replace()
而不是 add()
将片段添加到容器
当Activity由于方向改变而重新启动时,Activity被创建一次,ConfigureFragment被创建两次。
原因是如果应用程序被系统杀死,系统会自动恢复 activity 和碎片。这一幕发生在super.onCreate()。因此,上面的添加片段代码将在恢复的片段之上添加一个额外的片段,从而导致当前情况。 ScrollView 不能有多个子视图!
解决方案 2
如果您在 activity 的 onCreate() 方法中添加片段,则检查 savedInstanceState 变量(Bundle 对象)。重新创建 activity 时它不是空的,然后只添加你的片段
if (savedInstanceState == null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
ConfigureFragment fragment = new ConfigureFragment();
fragment.setReferences(MainActivity.this, (Controller) spinner.getSelectedItem());
fragmentTransaction.add(fragmentView.getId(), fragment, "");
fragmentTransaction.commit();
}