为什么调用 setRetainInstance(true) 时 TextView 的文本没有恢复?

Dam*_*les 2 android android-fragments

我为片段调用了 setRetainInstance(true) 。我在片段上添加了 EditText 和 TextView。旋转时,EditText 中的文本保留下来,但 TextView 中的文本消失了。

我想我可以手动恢复TextView的文本,但我想知道为什么系统会自动恢复EditText的文本,而不是TextView。我做错什么了吗?

重现步骤。

  1. 在 EditText 中输入“android”
  2. 按 [测试 1] 按钮。TextView 现在显示“android”
  3. 旋转设备。

结果

EditText 有“android”,但 TextView 是空的。

我的片段

public class MyFragment extends Fragment
{
    private static final String TAG = "MyFragment";
    EditText etInput;
    Button btnTest1;
    TextView tvMessage;
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    {
        Log.d(TAG, "onCreateView()");
        View v= inflater.inflate(R.layout.my_fragment, container, false);
        etInput = (EditText)v.findViewById(R.id.etInput);
        btnTest1 = (Button)v.findViewById(R.id.btnTest1);
        btnTest1.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                tvMessage.setText(etInput.getText().toString());
                Log.d(TAG, "btnTest1 was clicked");
            }
        });

        tvMessage = (TextView) v.findViewById(R.id.tvMessage);
        return v;
    }
}
Run Code Online (Sandbox Code Playgroud)

主活动.java

public class MainActivity extends AppCompatActivity
{
    String TAG = this.getClass().getName();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        Log.d(TAG, "onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();
        Fragment mf = fm.findFragmentById(R.id.placeholder);
        if(mf == null)
        {
            Log.d(TAG, "creating new my fragment");
            mf = new MyFragment();
            mf.setRetainInstance(true);
            fm.beginTransaction().add(R.id.placeholder, mf).commit();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

my_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
    <EditText

        android:id="@+id/etInput"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

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

    <Button
        android:id="@+id/btnTest1"
        android:text="Test 1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

活动_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
        <TextView
            android:text="Fragment Test"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

        <FrameLayout
            android:id="@+id/placeholder"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="0dp">

        </FrameLayout>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)

Eht*_*san 5

如果要启用 的自动恢复TextView,则需要在 xml(或调用)中将freezesText属性设置为。truesetFreezesText(true)

对于TextViewfreezesText默认值是false,但在情况下EditText,默认值是true

从文档freezesText

如果设置,除了元数据(例如当前光标位置)之外,文本视图还将在其冻结的冰柱中包含其当前的完整文本。默认情况下这是禁用的;当文本视图的内容未存储在持久性位置(例如内容提供程序)中时,它会很有用。对于 EditText,无论属性值如何,它始终处于启用状态。