为什么我要避免片段中的非默认构造函数?
我正在使用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
。
像onCreate
或onCreateView
的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); //... }
这样,如果分离并重新连接,则可以通过参数存储对象状态,就像连接到Intent
的bundles
一样。
如果你使用某个类的参数。 尝试这个
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,并使用主要的无参数构造函数和二级构造函数来实现碎片,只是将它们存储到一个包中,并将其设置为碎片参数,一切正常。