为什么要在Fragment中使用setArgument?
我们知道,当app的屏幕进行旋转或者其他的配置变化的时候,Fragment会执行它的周期变化,重新创建Fragment并加载(除非设置了setRetainInstance(true)),那么在重建的时候Fragment中的变量就会被重新初始化,运行中的状态将无法保留。
setArgument中的Bundle可以用来存放各种需要保持的数据,即使Fragment由于配置改变而重建,这些保存的数据也不会被清除。
下面我们将通过一个实例来测试一下,在实例的Fragment中共有3个TextView和一个Button,为了使测试的内容更清晰,下面把三个TextView对应的字符串列表如下:
textview1->banana, textview2->apple, textview3->pear
对应的三个字符串:
- mParam1: 在Fragment.newInstance中传入,并保存在setArgument中,但是在点击按钮时未更新到Argument中
- mParam2: Fragment中的私有变量,和Argument无任何交互
- mParam3: 在Fragment.newInstance中传入,并保存在setArgument中,并且在点击按钮时更新到了Argument中
测试程序的布局代码和java代码如下:
Fragment部局文件的代码
Fragment的Java代码
主Activity的代码
主Activity的布局文件代码
程序启动时显示默认如下内容:
textview1和textview3的值取自getArgument并显示在了屏幕上,当点击按钮时会重新给三个String变量赋值,并显示到textview中,如下图:
这时三个字符串变量都有了新的值,那么当我们把屏幕进行一下旋转操作后,看结果如何呢?
由图可知,字符串1回到了最初的状态(创建Fragment时传入的值),而字符串2被清除了。
字符串3因为在点击按钮的时候重新被保存在getArgument中,而没有任何的变化的被保留下来了。
因此大家在给Fragment传入参数的时候最好通过setArgument进行保存,而不是简单的通过一个变量进行保存。
注意:
- setArgument只能在Fragment中创建后(MyFragment fragment = new MyFragment())立即调用,如果在Fragment被附加到Activity中后再调用就会报错,可以在按钮的点击事件中添加一下setArgument的调用进行一下试验,应用将被异常终止。