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

Fragment newFragment = new MyFragment();

and

Fragment newFragment = MyFragment.newInstance();

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

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

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

我错过什么了吗?

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


当前回答

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

如果您正在使用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
}

快乐的编码。

其他回答

使用此代码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");

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

快乐的代码

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

话虽如此,传递东西到你的碎片,使他们可用后,一个碎片被Android重新创建是传递一个捆绑到setArguments方法。

因此,例如,如果我们想要传递一个整数到片段,我们将使用如下方式:

public static MyFragment newInstance(int someInt) {
    MyFragment myFragment = new MyFragment();

    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    myFragment.setArguments(args);

    return myFragment;
}

稍后在Fragment onCreate()中,你可以使用:

getArguments().getInt("someInt", 0);

即使Fragment被Android以某种方式重新创建,这个Bundle也将可用。

还要注意:setArguments只能在Fragment被附加到Activity之前被调用。

这种方法也记录在android开发者参考:https://developer.android.com/reference/android/app/Fragment.html

使用kotlin代码创建片段的实例。

在活动中写入

val fragment = YourFragment.newInstance(str = "Hello",list = yourList)

分段写作

fun newInstance(str: String, list: ArrayList<String>): Fragment {
        val fragment = YourFragment()
        fragment.arguments = Bundle().apply {
            putSerializable("KEY_STR", str)
            putSerializable("KEY_LIST", list)
        }
        return fragment
    }

使用相同的片段从bundle中检索数据

val str = arguments?.getString("KEY_STR") as? String
val list = arguments?.getSerializable("KEY_LIST") as? ArrayList<String>

你可以这样使用smth:

val fragment = supportFragmentManager.fragmentFactory.instantiate(classLoader, YourFragment::class.java.name)

因为这个答案现在已经被弃用了

在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。

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