我正在寻找一种有关如何注入片段并将参数传递给它的解决方案。 而且我没有找到任何合适的解决方案,因为通过构造函数注入片段意味着对状态不安全。
有什么方法可以执行此操作,而无需调用newInstance模式?
谢谢
最好。
答案 0 :(得分:0)
由于Android管理着您的Fragment的生命周期,因此您应该将以下问题分开:通过它们的捆绑包将通过状态传递给Fragment ,以及用可注入的deps注入Fragment 。通常,最好将这些分开的方法是提供一个static factory method,您可能将其称为 newInstance模式。
public class YourFragment extends Fragment {
// Fragments must have public no-arg constructors that Android can call.
// Ideally, do not override the default Fragment constructor, but if you do
// you should definitely not take constructor parameters.
@Inject FieldOne fieldOne;
@Inject FieldTwo fieldTwo;
public static YourFragment newInstance(String arg1, int arg2) {
YourFragment yourFragment = new YourFragment();
Bundle bundle = new Bundle();
bundle.putString("arg1", arg1);
bundle.putInt("arg2", arg2);
yourFragment.setArguments(bundle);
return yourFragment;
}
@Override public void onAttach(Context context) {
// Inject here, now that the Fragment has an Activity.
// This happens automatically if you subclass DaggerFragment.
AndroidSupportInjection.inject(this);
}
@Override public void onCreate(Bundle bundle) {
// Now you can unpack the arguments/state from the Bundle and use them.
String arg1 = bundle.getString("arg1");
String arg2 = bundle.getInt("arg2");
// ...
}
}
请注意,这是与您惯常使用的注入类型不同的方法:不是让片段实例通过注入而获得,而是告诉片段稍后将其自身插入活动。此示例使用dagger.android进行注入,即使Android在Dagger的控制范围之外创建Fragment实例,该示例也使用子组件和members-injection methods注入@Inject-annotated
字段和方法。
还要注意,Bundle是通用键值存储;我使用“ arg1”和“ arg2”代替了更多创意名称,但是您可以使用任何想要的String键。请参见Bundle及其超类BaseBundle,以查看Bundle在其get
和put
方法中支持的所有数据类型。该捆绑包对于保存片段数据也很有用;如果您的应用程序被电话打断并且Android破坏了Activity以节省内存,则可以使用onSaveInstanceState
将表单字段数据放入捆绑包中,然后将该信息恢复到onCreate
中。
最后,请注意,您不需要创建静态工厂方法,例如newInstance
;您还可以让您的使用者创建一个new YourFragment()
实例并自己传递一个特定的Bundle设计。但是,到那时,Bundle结构将成为您的API的一部分,而您可能并不需要。通过创建静态工厂方法(或Factory对象或其他结构),您可以将Bundle设计作为Fragment的实现细节,并提供文档化且保存良好的结构,供消费者创建新实例。