我已经看到了在应用程序中实例化一个新Fragment的两个通用实践:

Fragment newFragment = new MyFragment();

and

Fragment newFragment = MyFragment.newInstance();

第二个选项使用静态方法newInstance(),通常包含以下方法。

public static Fragment newInstance() 
{
    MyFragment myFragment = new MyFragment();
    return myFragment;
}

起初,我认为主要的好处是,我可以重载newInstance()方法,以便在创建新的Fragment实例时提供灵活性——但我也可以通过为Fragment创建重载构造函数来实现这一点。

我错过什么了吗?

一种方法相对于另一种方法有什么好处?还是说这只是一个很好的练习?


当前回答

使用newInstance()的唯一好处是:

You will have a single place where all the arguments used by the fragment could be bundled up and you don't have to write the code below everytime you instantiate a fragment. Bundle args = new Bundle(); args.putInt("someInt", someInt); args.putString("someString", someString); // Put any other arguments myFragment.setArguments(args); Its a good way to tell other classes what arguments it expects to work faithfully(though you should be able to handle cases if no arguments are bundled in the fragment instance).

因此,我认为使用静态newInstance()来实例化一个片段是一个很好的实践。

其他回答

我最近在这里。但我知道的一些事也许能帮到你。

如果您正在使用Java,那么没有什么需要更改的。但是对于Kotlin开发人员来说,下面是一些代码片段,我认为它们可以让你成为一个运行的基础:

父母片段:

inline fun <reified T : SampleFragment> newInstance(text: String): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().also { it.putString("key_text_arg", text) }
    }
}

正常调用

val f: SampleFragment = SampleFragment.newInstance("ABC")
// or val f = SampleFragment.newInstance<SampleFragment>("ABC")

你可以在子fragment类中扩展父init操作:

fun newInstance(): ChildSampleFragment {
    val child = UserProfileFragment.newInstance<ChildSampleFragment>("XYZ")
    // Do anything with the current initialized args bundle here
    // with child.arguments = ....
    return child
}

快乐的编码。

在android中使用参数实例片段的最佳实践是在你的片段中有静态工厂方法。

public static MyFragment newInstance(String name, int age) {
    Bundle bundle = new Bundle();
    bundle.putString("name", name);
    bundle.putInt("age", age);

    MyFragment fragment = new MyFragment();
    fragment.setArguments(bundle);

    return fragment;
}

您应该避免使用片段的实例来设置字段。因为每当android系统重新创建fragment时,如果它觉得系统需要更多内存,它就会使用不带参数的构造函数重新创建fragment。

你可以在这里找到更多关于用参数实例化片段的最佳实践的信息。

使用此代码100%修复您的问题

在firstFragment中输入这个代码

public static yourNameParentFragment newInstance() {

    Bundle args = new Bundle();
    args.putBoolean("yourKey",yourValue);
    YourFragment fragment = new YourFragment();
    fragment.setArguments(args);
    return fragment;
}

这个示例发送布尔数据

和在SecendFragment

yourNameParentFragment name =yourNameParentFragment.newInstance();
   Bundle bundle;
   bundle=sellDiamondFragments2.getArguments();
  boolean a= bundle.getBoolean("yourKey");

必须值在第一个片段是静态的

快乐的代码

我不同意yydi的回答:

如果Android决定稍后重新创建Fragment,它会调用 片段的无参数构造函数。重载 构造函数不是解决方案。

我认为这是一个很好的解决方案,这正是它被Java核心语言开发的原因。

确实,Android系统可以破坏和重建你的碎片。所以你可以这样做:

public MyFragment() {
//  An empty constructor for Android System to use, otherwise exception may occur.
}

public MyFragment(int someInt) {
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    setArguments(args);
}

它将允许您稍后从getArguments()中提取someInt,即使该Fragment已被系统重新创建。这是比静态构造函数更优雅的解决方案。

在我看来,静态构造函数是无用的,不应该使用。此外,如果将来你想扩展这个Fragment并向构造函数添加更多功能,它们也会限制你。使用静态构造函数你不能这样做。

更新:

Android增加了标记所有非默认构造函数错误的检查。 由于上面提到的原因,我建议禁用它。

setArguments()没有用。这只会带来混乱。

public class MyFragment extends Fragment {

    public String mTitle;
    public String mInitialTitle;

    public static MyFragment newInstance(String param1) {
        MyFragment f = new MyFragment();
        f.mInitialTitle = param1;
        f.mTitle = param1;
        return f;
    }

    @Override
    public void onSaveInstanceState(Bundle state) {
        state.putString("mInitialTitle", mInitialTitle);
        state.putString("mTitle", mTitle);
        super.onSaveInstanceState(state);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        if (state != null) {
            mInitialTitle = state.getString("mInitialTitle");
            mTitle = state.getString("mTitle");
        } 
        ...
    }
}