Fragment.setArguments()的初衷。

简介

在我们平常开发的时候Fragment是经常使用的,而我们创建一个Fragment对象的时候一般都会 通过 new Fragment()构造方法来实现,如果要传递参数我们一般会重载构造方法,例如 new Fragment(Parameter p)。

但是这样的做法是不被提倡的,如果你重载构造函数之后,系统会有一个warning,如下:

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

这个警告的意思就是,尽量避免使用 不是默认的构造函数(也就是我们重载的构造函数):通过 使用默认的构造函数 加上 Fragment.setArguments(Bundle)来取代。

接下来我们来看一下这两种方式:

重载的构造函数:

public class MyFragment extends Fragment {

    public MyFragment(MyParameter p){
        //将参数保存起来
    }

}

如果在创建Fragment的时候,使用 MyFragment mf = new MyFragment(parameter)

来传递参数。

通过Fragment.setArguments(Bundle)

public class MyFragment extends Fragment {

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

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

        return myFragment;
    }
}

这种方式在创建Fragment的时候,使用MyFragment mf = MyFragment.newInstance(paramter) 来传递参数。

分析

乍一看这两种方法似乎没有什么本质区别,但是实际上 方法一(重载构造函数)是有一个隐患的。

根据Android文档说明,当一个fragment重新创建的时候,系统会再次调用 Fragment中的默认构造函数。 注意这里:是 默认构造函数

这句话更直白的意思就是:当你小心翼翼的创建了一个带有重要参数的Fragment的之后,一旦由于什么原因(横竖屏切换)导致你的Fragment重新创建。——-很遗憾的告诉你,你之前传递的参数都不见了,因为recreate你的Fragment的时候,调用的是默认构造函数

对比

而使用系统推荐的 Fragment.setArguments(Bundle)来传递参数。就可以有效的避免这一个问题,当你的Fragment销毁的时候,其中的Bundle会保存下来,当要重新创建的时候会检查Bundle是否为null,如果不为null,就会使用bundle作为参数来重新创建fragment.

疑问:

当fragment重建的时候,怎么获取之前的参数呢?

以上面的代码为例:我们可以重写 fragment的onCreate()方法。

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

当fragment重现创建,调用onCreate方法,然后就可以取得之前的参数了,然后就可以尽情使用了。

bundle是如何将参数保存下来,然后重建的时候再利用呢?

这个问题可以移步这篇博客。

注意:

setArguments can only be called before the Fragment is attached to the Activity.

setArguments方法的调用必须要在Fragment与Activity关联之前。

这句话可以这样理解,setArgument方法的使用必须要在FragmentTransaction 的commit之前使用。

详见:连接。

参考资料1:

参考资料2

参考资料3

时间: 2024-10-14 05:17:16

Fragment.setArguments()的初衷。的相关文章

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

“Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle)instead” 出現這個問題時 使用Window->Android->Lint Error Checking 在 Correctness類別裡,找到ValidFragment ,設定為Ingore就可以了. 转载:http://www.dotblogs.com.tw/newmonke

Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数(转)

Fragment在Android3.0开始提供,并且在兼容包中也提供了Fragment特性的支持.Fragment的推出让我们编写和管理用户界面更快捷更方便了. 但当我们实例化自定义Fragment时,为什么官方推荐Fragment.setArguments(Bundle bundle)这种方式来传递参数,而不推荐通过构造方法直接来传递参数呢?为了弄清这个问题,我们可以做一个测试,分别测试下这两种方式的不同 首先,我们来测试下通过构造方法传递参数的情况 public class FramentT

Fragment.setArguments()

在我们平常开发的时候Fragment是经常使用的,而我们创建一个Fragment对象的时候一般都会 通过 new Fragment()构造方法来实现,如果要传递参数我们一般会重载构造方法,例如 new Fragment(Parameter p). 但是这样的做法是不被提倡的,如果你重载构造函数之后,系统会有一个warning,如下: Avoid non-default constructors in fragments: use a default constructor plus Fragme

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

“Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle)instead” 出現這個問題時 使用Window->Android->Lint Error Checking 在 Correctness類別裡,找到ValidFragment ,設定為Ingore就可以了. 转载:http://www.dotblogs.com.tw/newmonke

Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数

Fragment在Android3.0开始提供,并且在兼容包中也提供了Fragment特性的支持.Fragment的推出让我们编写和管理用户界面更快捷更方便了. 但当我们实例化自定义Fragment时,为什么官方推荐Fragment.setArguments(Bundle bundle)这种方式来传递参数,而不推荐通过构造方法直接来传递参数呢? 为了弄清这个问题,我们可以做一个测试,分别测试下这两种方式的不同 首先,我们来测试下通过构造方法传递参数的情况 1 public class Frame

采用Fragment.setArguments(Bundle bundle)来传递参数,而不用构造函数

google官方推荐用setArgument来传参而不是用构造函数. 因为当切换横竖屏时,Fragment会调用自己的无参构造函数,那么在构造函数传参就会失效. public class FramentTestActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setConten

Fragment传值为什么要通过setArguments()和Fragment的生命周期

在Fragment2中,新建一个函数:newInstance(String  text)来接收传过来的参数: 新建一个Fragment2实例,然后将参数通过SetArguments设置到其中: public static Fragment2 newInstance(String text) {        Fragment2 fragment = new Fragment2();        Bundle args = new Bundle();        args.putString(

android中传递复杂参数,Activity之间通过Intent使用bundle,fragment之间和Activityty通过setArguments使用bundle

在Android开发中,Activity之间通过Intent使用bundle,fragment之间和Activityty通过setArguments使用bundle,对于一些简单的参数传递比较简单,而且方式也有多种,这个就不介绍了.在这里介绍一下复杂的参数传递,比如传递集合ArrayList,对象ArrayList<Object>. 无论是Activity之间参数传递,还是Fragment之间参数传递,或者是Activity与Fragment之间,都要使用Bundle,方式基本相同.Bundl

切换Fragment时实现数据保持

摘要 Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用.可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期. Fragment设计初衷是为了简化不同屏幕分辨率的开发难度,他将代表一个功能的UI及其相关数据看做一个模块,以便达到复用.可以将Fragment看作是一个可以嵌入布局中的activity,有自己的生命周期.比如我现在在手机上有activityA和activityB,但是在平板上有更大的