成员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()方法,我认为它们是封装我的FragmentnewsetArguments()调用的简单方法; 我有时会提供额外的MyFragment newInstance(String singleIdOfWhatToDisplay) ,它MyFragment newInstance(String singleIdOfWhatToDisplay)创buildBundleFragment ,并返回一个准备好的Fragment实例。

我发现这是一个非常混乱的问题(Android景观中的许多问题之一)。

setArguments()是Android非常无用的需要为Fragments提供无参数构造函数的解决方法。

我的困惑波澜起伏。 首先,你自然在你的Fragment覆盖的方法(例如onCreateonCreateView )会接收一个代表你的FragmentsavedInstanceStateBundle参数。 这个实例状态显然与通过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。 我真的很讨厌这个