为什么我要避免片段中的非默认构造函数?

我正在使用Fragments创build一个应用程序,在其中一个应用程序中,我创build了一个非默认的构造函数,并得到以下警告:

 Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead 

有人能告诉我为什么这不是一个好主意吗?

你也可以build议我怎么做到这一点:

 public static class MenuFragment extends ListFragment { public ListView listView1; Categories category; //this is my "non-default" constructor public MenuFragment(Categories category){ this.category = category; }.... 

不使用非默认的构造函数?

创build一个bundle对象并插入你的数据(在这个例子中你的Category对象)。 要小心,除非是可序列化的,否则不能将这个对象直接传递给bundle。 我认为最好在碎片中构build你的对象,并且只把一个id或者别的东西放进bundle中。 这是创build和附加包的代码:

 Bundle args = new Bundle(); args.putLong("key", value); yourFragment.setArguments(args); 

之后,在你的片段访问数据:

 Type value = getArguments().getType("key"); 

就这样。

好像没有一个答案实际上回答“为什么使用bundle传递参数而不是非默认构造函数”

你应该通过捆绑传递参数的原因是因为当系统恢复一个fragment (例如在configuration改变时),它会自动恢复你的bundle

onCreateonCreateView的callback应该从bundle读取参数 – 这样你就可以保证将fragment的状态正确地恢复到fragment初始化的相同状态(注意,这个状态可以和传递的onSaveInstanceState bundle不同到onCreate/onCreateView

使用静态newInstance()方法的build议只是一个build议。 您可以使用非默认构造函数,但要确保在该构造函数体内的bundle装入初始化参数。 并读取onCreate()onCreateView()方法中的参数。

你的Fragment不应该有构造函数,因为FragmentManager如何实例化它。 你应该有一个用你需要的参数定义的newInstance()静态方法,然后将它们打包并设置为片段的参数,以后可以使用Bundle参数访问它们。

例如:

 public static MyFragment newInstance(int title, String message) { MyFragment fragment = new MyFragment(); Bundle bundle = new Bundle(2); bundle.putInt(EXTRA_TITLE, title); bundle.putString(EXTRA_MESSAGE, message); fragment.setArguments(bundle); return fragment ; } 

并阅读onCreate这些参数:

 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); title = getArguments().getInt(EXTRA_TITLE); message = getArguments().getString(EXTRA_MESSAGE); //... } 

这样,如果分离并重新连接,则可以通过参数存储对象状态,就像连接到Intentbundles一样。

如果你使用某个类的参数。 尝试这个

 SomeClass mSomeInstance; public static final MyFragment newInstance(SomeClass someInstance){ MyFragment f = new MyFragment(); f.mSomeInstance = someInstance; return f; } 

我用过的方法,它正在工作!

 public FragmentHome() { // Required empty public constructor } public void FragmentHomeConstructor(Context context, String stringBundle) { mContext = context; mStringBundle = stringBundle; } 

在fragment的oncreate()方法中做到这一点,以获得上下文没有任何错误!

 mContext = this.getActivity(); 

在你的activity的oncreate()方法中:

 FragmentHome fragmentHome = new FragmentHome(); fragmentHome.FragmentHomeConstructor(mContext, mStringBundle); 

我认为,静态构造函数和两个构造函数(空和参数化函数将参数存储到Fragment的参数包中)没有区别,最有可能的是,创build这个经验法则是为了减less在Java中实现无参数构造函数的可能性,这在过载时并不是隐式生成的。

在我的项目中,我使用Kotlin,并使用主要的无参数构造函数和二级构造函数来实现碎片,只是将它们存储到一个包中,并将其设置为碎片参数,一切正常。