对于普通(非嵌套片段),我使用以下方法
1)创建用于设置片段依赖性的依赖项(...)方法
class MyFragment extends MyFragment {
void dependencies(Deps deps);
}
2)在MyFragment parent的活动onAttachFragment()方法中我只提供了片段的依赖
class MyActivity{
void onAttachFragment(Fragment f){
((MyFragment)f).dependencies(deps);
}
}
对于嵌套片段,不再有 onAttachFragment 片段被调用。 为嵌套片段提供片段的依赖性似乎非常麻烦。那我怎么能为它提供依赖呢?
答案 0 :(得分:5)
只需将其作为活动的上下文。为您的活动依赖项创建一个getter。无论是否嵌套,片段都可以访问父活动。转换上下文,然后调用getter以获取嵌套活动中的依赖项。
答案 1 :(得分:2)
如果MyFragment
取决于MyNestedFragment
,则MyNestedFragment
取决于Deps
;因此MyFragment
也取决于Deps
。当然,调用MyNestedFragment
时不存在Activity.onAttachFragment()
的实例,因此您必须等到MyFragment.onCreateView()
中的布局膨胀之后再提供MyNestedFragment
的依赖关系
public class MyActivity {
...
void onAttachFragment(Fragment f){
((MyFragment)f).dependencies(deps);
}
public static class MyFragment extends Fragment {
private Deps deps;
void dependencies(Deps deps) {
this.deps = deps;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// <fragment> element in fragment_main layout has
// android:tag set to nested_fragment
((MyNestedFragment)getChildFragmentManager()
.findFragmentByTag("nested_fragment"))
.dependencies(this.deps);
return rootView;
}
}
public static class MyNestedFragment extends Fragment {
void dependencies(Deps deps) {
...
}
}
...
}
如果所有这些看起来有点混乱,那是因为片段不是POJO,你可以以任意方式连线。他们的生命周期必须由嵌套的FragmentManagers管理。如果您以编程方式创建片段而不是使用&lt; fragment&gt;元素,您将以更复杂的代价更多地控制其生命周期。
如果您想将Android视为IoC容器,那么RoboGuice可能就是您所寻找的:
public class MyActivity extends roboguice.activity.RoboFragmentActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
// This only needs to be called once for the whole app, so it could
// be in the onCreate() method of a custom Application subclass
RoboGuice.setUseAnnotationDatabases(false);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public static class MyNestedFragment extends Fragment {
@Inject
private Deps deps;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// this isn't necessary if you extend RoboFragment
roboguice.RoboGuice.getInjector(activity).injectMembers(this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//This would not even be possible in the previous example
// because onCreateView() is called before dependencies()
// can be called.
deps.method();
View rootView = inflater.inflate(R.layout.fragment_nested, container, false);
return rootView;
}
}
}
@Singleton
public class Deps {
public void method() {
System.out.println("Deps.method()");
}
}
答案 2 :(得分:2)
您尝试在附加片段时设置依赖项。而不是这样,尝试在需要时从片段中获取依赖关系。有一个例子:
public class MyActivity extends Activity {
public Deps getDepsForFragment(Fragment fragment) {
if (fragment instanceof MyFragment) {
return depsForMyFragment;
} else if (fragment instanceof MyNestedFragment) {
return depsForMyNestedFragment;
} else {
return null;
}
}
}
public class MyFragment extends Fragment {
private Deps deps;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
MyActivtiy myActivity = (MyActivtiy) context;
deps = myActivity.getDepsForFragment(this);
} catch (ClassCastException e) {
throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies.");
}
}
}
// this is the same as the MyFragment
public class MyNestedFragment extends Fragment {
private Deps deps;
@Override
public void onAttach(Context context) {
super.onAttach(context);
try {
MyActivtiy myActivity = (MyActivtiy) context;
deps = myActivity.getDepsForFragment(this);
} catch (ClassCastException e) {
throw new ClassCastException("This fragment attached to an activity which can't provide the required dependencies.");
}
}
}
当然,您可以为活动中的deps制作单独的方法(例如getDepsForMyFragment
和getDepsForMyNestedFragment
)。
答案 3 :(得分:1)
只需保留层次结构逻辑,它应该是这样的:
class MyActivity{
void onAttachFragment(Fragment f){
((MyFragment)f).dependencies(deps);
}
}
class MyFragment extends MyFragment {
void dependencies(Deps deps) {
//TODO: do dependencies of my fragment before
((MyNestedFragment)childF).nestedDependencies(deps);
//TODO: do dependencies of my fragment after
}
}
class MyNestedFragment extends MyNestedFragment {
void nestedDependencies(Deps deps);
}