【问题标题】:Why is the text of TextView not restored when setRetainInstance(true) has been called?为什么调用 setRetainInstance(true) 后 TextView 的文本没有恢复?
【发布时间】:2016-04-14 13:58:06
【问题描述】:

我为片段调用了 setRetainInstance(true)。我在片段上添加了 EditText 和 TextView。旋转时,EditText 中的文字存活,但 TextView 中的文字消失了。

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

重现步骤。

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

结果

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

MyFragment.java

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

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

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>

activity_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>

【问题讨论】:

  • setRetainInstanceState 将保留 Fragment 本身的状态,而不是该 Fragment 中包含的 UI/视图。为此,您需要在片段中全局保存一些值,然后在 onCreateView 中将视图重置为这些值。
  • 我在某处读到,如果您在 xml 中明确定义片段(使用 标签),这将起作用,但我不知道它是否对您有帮助
  • 那为什么EditText的文字会自动恢复呢?
  • @SinJeong-hun 我阅读的文档对于几个 UI 组件有同样的问题
  • 您的意思是用 替换 吗?我试过了,但它导致了通货膨胀异常。

标签: android android-fragments


【解决方案1】:

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

对于TextViewfreezesText 默认值为false,但对于EditText,默认值为true

来自freezesText的文档:

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

【讨论】:

  • freezesText 也适用于 Button,如果您想恢复其上的文本,因为 Button 是 TextView。
猜你喜欢
  • 2013-08-27
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2014-01-28
  • 2012-06-25
  • 2019-12-17
  • 1970-01-01
相关资源
最近更新 更多