成员variables与片段中的setArguments
我注意到,在Fragments(特别是DialogFragment )的Android引用中,他们做了一些与我所期望的不同的事情:
1)。 使用public static foo newInstance()
方法而不是构造函数。
2)。 使用setArguments而不是成员variables将值传递给onCreateDialog。
我读过使用reflectionnewInstance似乎是可取的。 不过,我真的不明白他们为什么通过一个包传递参数。 我会虽然使用成员variables会更安全(不使用string从地图中获取),并会有更less的开销。
有什么想法吗?
我也偶然发现了这一点,发现通过实例字段使用参数Bundle
的一些优点:
-
如果在
Bundle
,Android系统知道它,并且可以创build和销毁您的Fragment
(使用必需的无参数/默认构造函数和常用的生命周期方法),并再次传入参数bundle。 这样一来,低内存杀死狂潮或最终的方向变化(在经过较less旋转的仿真器中开发之后,经常会首先将其部署到真实的设备上),不会有任何争论。 -
您可以将
Activity
的额外Bundle
按原样传递给布局中embedded的Fragment
; 例如我经常使用这个,当我有一个Activity
,显示一个Fragment
“全屏”,需要一些ID(或ContentProvider
URI)知道要显示/做什么。 我有时甚至在我传递它之前添加更多的东西到一个Bundle
(或一个副本),例如@Override protected void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (savedInstanceState == null) { // not a re-creation final Bundle args = new Bundle(getIntent().getExtras()); args.putInt(CoverImageFragment.BACKGROUND_RESOURCE, android.R.color.black); final Fragment fragment = CoverImageFragment.newInstance(args); getSupportFragmentManager() .beginTransaction() .add(android.R.id.content, fragment) .commit(); } }
-
它使开发
Fragment
的方式接近于Activity
,即Bundle
作为“input参数,没有例外”。
至于你提到的缺点:
-
我认为开销是微乎其微的,因为你很可能不会在一个紧密的循环中查询
Bundle
,所以在onCreate()
,onViewCreate()
等方面获得你的参数数据并不是那么糟糕。 -
对于types安全性,
Bundle
具有所有不同的getXXXX()
方法,甚至可以通过重载来提供缺省值,如果缺less某些东西的话。
至于newInstance()
方法,我认为它们是封装我的Fragment
的new
和setArguments()
调用的简单方法; 我有时会提供额外的MyFragment newInstance(String singleIdOfWhatToDisplay)
,它MyFragment newInstance(String singleIdOfWhatToDisplay)
创buildBundle
和Fragment
,并返回一个准备好的Fragment
实例。
我发现这是一个非常混乱的问题(Android景观中的许多问题之一)。
setArguments()
是Android非常无用的需要为Fragments提供无参数构造函数的解决方法。
我的困惑波澜起伏。 首先,你自然在你的Fragment
覆盖的方法(例如onCreate
, onCreateView
)会接收一个代表你的Fragment
的savedInstanceState
的Bundle
参数。 这个实例状态显然与通过setArguments()
存储的值没有任何关系,并且通过setArguments()
检索。 两者都使用一个Bundle
,两个Bundles
都可能在同一个重写的方法中被访问,两者之间也没有任何关系。
其次,目前还不清楚Android如何使用setArguments()
。 Android调用你的无参数构造函数来重build你的Fragment
旋转,但显然也会调用当构造Fragment
时最后调用的setArguments()
方法。
咦????
令人惊叹的,但真实的。 所有这些创build具有setArguments()
疯狂的Bundles
是为了弥补无参数的Fragment
构造函数的需要。
总之,我正在使用静态newInstance
方法来创build我的Fragment
。
public MyFragment() { //satisfy Android } public static MyFragment newInstance(long record_id) { Log.d("MyFragment", "Putting " + record_id + " into newInstance"); MyFragment f = new MyFragment(); Bundle args = new Bundle(); args.putLong("record_id", record_id); f.setArguments(args); return f; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * Perform an immediate check of arguments, * which ARE NOT the same as the bundle used * for saved instance state. */ Bundle args = getArguments(); if(args != null) { record_id = args.getLong("record_id"); Log.d("MyFragment", "found record_id of " + String.valueOf(record_id)); } if(savedInstanceState != null) { //now do something with savedInstanceState } }
我对Android编程非常新颖,但这是我目前对这个问题的理解:
碎片的构造函数不能有任何参数。 当你的活动暂停时,你的片段可以被释放。 在您的活动恢复之前,系统会创build一个调用构造函数的Fragment的新版本。 如果使用非默认构造函数,Android应该如何知道Fragments构造函数的参数的types和值是什么?
我不相信捆绑被释放。 这个bundle保持在正确的位置,这样在用默认的构造函数重新创build之后,它可以传回给你的Fragment。
Philipp Reichart在他的post中回避了这个问题(实际上不止于此)。
只是想为参数添加一个缺点是您必须dynamic创build片段。 由于参数不能很好地工作,如果你从XML创build。 我真的很讨厌这个