Fragments 之间的 SavedInstanceStateNull 为 null

SavedInstanceStateNull between Fragments is null

我有一个显示按钮列表的片段,每个按钮都有自己的 ID。当用户单击按钮时,我试图用另一个替换当前片段。替换片段后,我立即向包中添加参数。从我在调试模式中可以看出,该部分正在 100% 工作。但是,当我们到达新片段时,"savedInstanceState" 状态将始终为空。

我已经阅读了几篇关于此的文章,但我很困惑,因为我试图设置捆绑包并替换片段,就像我从 activity 到第一个片段时所做的那样,它是仍然无法正常工作。

MyActivity.java(这是有效的,正在设置所有值):

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
MyFirstFragment fragment = new MyFirstFragment();
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame,fragment);
        fragmentTransaction.commit();
        Intent i = getIntent();
        value = i.getExtras().getString("key");
        Bundle bundle = new Bundle();
        bundle.putString("key",value);
        fragment.setArguments(bundle);
}

MyFirstFragment.java(也有效):

public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_first, container, false);
final String value = getArguments().getString("key");
myButton.setOnClickListener(new View.OnClickListener(){
                    @Override
                    public void onClick(View v){
                        String gid = Integer.toString(v.getId());

                        MySecondFragment secondfragment = new MySecondFragment();
                        Bundle secondFragmentBundle = new Bundle();
                        secondFragmentBundle.putString("key",value);
                        secondFragmentBundle.putString("id",id);
                        secondfragment.setArguments(secondFragmentBundle);

                        FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
                        fragmentTransaction.replace(R.id.frame,secondfragment);
                        fragmentTransaction.commit();
                    }
                });

MySecondFragment(为 savedInstanceState 和所有包组件获取空值!):

@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_second, container, false);

        value = getArguments().getString("key");
        id = getArguments().getString("id");
}

片段附加到 Activity 后,您不能在片段上设置参数。

您的问题是由于对 Fragment 创建的困惑造成的。您在问题中提供的不是将参数发送到另一个 Fragment 类型的正确方法。

创建片段时将参数传递给片段的事实上的标准方法是使用 static factory method,通常称为 newInstance()。您应该以这种方式设置参数,并且应该在提交 FragmentTransaction 之前这样做——但是,从技术上讲,您可以在提交事务后立即这样做而不会产生不良影响。这是因为当一个 Fragment 被提交时,它不会立即 attached/created,而是在主线程中排队。

以下是您的操作方式:

在您的 Fragment class 中编写一个名为新实例的方法。请确保为系统保留一个 public 默认(无参数)构造函数以在后台处理事情。

public MyFirstFragment extends Fragment {

public MyFirstFragment(){
//constructor - don't use this to create a new fragment directly
}

public static MyFirstFragment newInstance(String argument1, String argument2) {

    // This is where you set the Fragment arguments:

    MyFirstFragment instance = new MyFirstFragment();
    Bundle arguments = new Bundle();

    // add whatever arguments you need to the bundle
    arguments.putString("ARGUMENT_1_KEY", argument1);
    arguments.putString("ARGUMENT_2_KEY", argument2);

    //Set the arguments on the new fragment instance
    instance.setArguments(arguments);

    return instance;
}

// recover the values in onCreate:
@Override
public void onCreate(Bundle savedInstanceState) {

    // an easy way to check if this is a new instance is to null-check the saved state Bundle
    if (savedInstanceState == null) {
        String argument1 = getArguments().getString("ARGUMENT_1_KEY");
        String argument2 = getArguments().getString("ARGUMENT_2_KEY");
    } else {
        // restore whatever you need from savedInstanceState bundle
    }

}

关键点 - 参数被传递到 newInstance() 方法(这些可以是任何你想要的,只要类型是 allowed)。 newInstance() 方法强制执行参数类型,并防止在片段已经附加到 activity.

之后设置它们

在此之后,在您的 Activity.onCreate() 方法中:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String argument1 = "some information";
        String argument2 = "other information";

        MyFirstFragment fragment = MyFirstFragment.newInstance(argument1, argument2);
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.replace(R.id.frame,fragment);
        fragmentTransaction.commit();
}