java - SavedInstanceState Null fragment 之间为 null

标签 java android android-fragments android-activity bundle

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

我已经阅读了几篇关于此的文章,但是我很困惑,因为我试图以与从 Activity 到第一个 fragment 时相同的方式设置 bundle 并替换 fragment ,但它仍然无法工作。

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 和所有 bundle 参数为 null!):

@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");
}

最佳答案

在 Fragment 附加到 Activity 后,您无法在 Fragment 上设置参数。

您的问题是由于对 Fragment 创建的混淆引起的。您在问题中提供的内容不是将参数发送到其他 Fragment 类型的正确方法。

创建 Fragment 时将参数传递给 Fragment 的事实上的标准方法是使用 static factory method ,一般称为newInstance()。您应该以这种方式设置参数,并且应该在提交 FragmentTransaction 之前执行此操作 - 但是,从技术上讲,您可以在提交事务后立即执行此操作,而不会产生任何不良影响。这是因为当提交 Fragment 时,它不会立即附加/创建,而是在主线程上排队。

以下是您的操作方法:

在 Fragment 类中编写一个名为 new instance 的方法。请务必留下一个公共(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() 方法强制执行参数类型,并防止在 fragment 已附加到 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();
}

关于java - SavedInstanceState Null fragment 之间为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42737502/

相关文章:

java - Hibernate 删除级联

android - 向右浮动 android

Android ScaleAnimation,如何使用它使项目变小而不是变大

java - 如何保存字符串?

java - Android - 在内部存储上保存 Int 错误

java - 使用JavaFX图表API绘制图表图像

android - 使用 fragment 时 viewModelFactory 变量尚未初始化

android - 如何将 Activity 包含在 fragment 选项卡中?

java - 任何人都有 Java 启动画面的简单代码示例吗?

Android VideoView - 检测视频中的时间点