【问题标题】:Preventing Fragment restoreViewState()防止片段 restoreViewState()
【发布时间】:2015-01-18 21:44:25
【问题描述】:

我有一个可以使用片段 (FooFragment) 配置的对象 Foo。 Foo 类包含对 FooFragment 的静态引用和方法 public Fragment getConfigurationFragment();此方法将当前对象分配给 FooFragment 并返回它。

public class Foo{
    private static FooFragment fooFragment = new FooFragment();

    public Fragment getConfigurationFragment(){
        fooFragment.setObject(this);
        return fooFragment;
    }

    //various getters and setters
}

FooFragment大致如下:

public class FooFragment extends Fragment{
    private Foo f;

    private EditText field1, field2, etc;

    public void setObject(Foo f){
        this.f = f;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //inflate view
        setupFieldListeners();
        //return view object
    }

    @Override
    private void onStart(){
        super.onStart();
        setupFields();
    }

    private void setupFields(){
        field1.setText(f.getField1());
        field2.setText(f.getField2());
        //etc
    }

    private void setupListeners(){
         field1.addTextChangedListener(new TextWatcher(){
             @Override
             public void afterTextChanged(Editable e){
                 f.setField1(e.getText().toString());
         });
             //Other empty necessary methods

         field2.addTextChangedListener(new TextWatcher(){
             //...
         });
    }
}

当我第一次在对象 foo1 上使用 Fragment 时,一切正常。显示正确的信息,一切正常。

当我在另一个对象 foo2 上第二次使用 Fragment 时,打开 Fragment 会导致 foo1 中的所有属性(field1、field2 等)写入 foo2。我相信这是因为当再次添加 Fragment 时,restoreViewState() 方法运行,它将 EditText 字段的值更改为 foo1 的值,导致 afterTextChanged() 方法触发,并将 foo1 的值写入foo2.

我已尝试以下方法来解决此问题:

-每当调用 getConfigurationFragment() 时创建一个新的 FooFragment 对象。这可行,但我认为这不是最佳选择,因为我知道最好避免在移动平台上不必要地创建对象。

-覆盖 Fragment 中的 onSaveInstanceState() 并发送一个 null Bundle。这不起作用,因为在 Fragment 关闭时它看起来不会被调用。它不起作用。

-在 OnStart()、OnResume()、OnCreateView() 中调用 setupFields()。这些都不起作用,因为当 restoreViewState() 运行时,它会破坏 foo2 对象。

-在 onCreate() 和 onCreateView() 中将 Bundle 设置为 null。没用。

如何才能让 foo2 信息加载到重用的 Fragment 中?

我对 FragmentTransaction 机制没有最好的理解。是否有可能以某种方式告诉 FragmentManager 恢复 View 状态?

重用配置片段的想法是否存在根本性缺陷并且需要避免?如果有,为什么?

还有什么其他的魔法可以让它起作用吗?

提前感谢您的宝贵时间。

【问题讨论】:

  • 这看起来是一个很奇怪的结构。你想用这种模式实现什么? “使用”片段到底是什么意思?您是存储本地配置还是全局配置?请为您的问题添加更多详细信息。
  • 1 - 我试图通过仅创建 FooFragment 对象的一个​​实例并在我想编辑 Foo 的属性时重用它来最大限度地减少对象创建和垃圾收集的数量。 2-通过使用片段,我的意思是在给定的 foo 上运行 getConfigurationFragment() 方法。 3 - 我试图在问题中提供尽可能多的细节。你能告诉我更具体的细节吗?

标签: java android android-fragments state


【解决方案1】:

我在片段视图状态恢复方面也遇到过类似的问题。防止它的一种方法是在调用 restoreViewState() 之前清除 package-private mSavedViewState 字段:

package androidx.fragment.app;

import android.os.Bundle;
import android.view.View;

public class StatelessFragment extends Fragment {

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        mSavedViewState = null;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2015-12-05
    • 1970-01-01
    相关资源
    最近更新 更多