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();
}