我有一个关于android中“正确编程”的问题。
我目前正在开发一个使用片段的应用程序。它包括动态地向活动添加片段、从xml膨胀的片段、从xml嵌套的片段或动态地添加的片段。就说,什么都有一点。
这个问题关注的概念是与片段相关的通信过程。所以,我读过文档,这不是我第一次尝试使用片段。
常识(和文档)告诉我们,如果一个片段想要与它的活动对话或通信,我们应该使用一个接口。
例子:
测试片段
public class TestFragment extends Fragment {
private TestFragmentInterface listener;
public interface TestFragmentInterface {
void actionMethod();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (getActivity() instanceof TestFragmentInterface) {
listener = (TestFragmentInterface) getActivity();
}
// sending the event
if (listener != null) listener.actionMethod();
}
}
测试性
public class Test implements TestFragmentInterface {
@Override
public void actionMethod() {
..
}
}
这里一切都很好。
这提高了可重用性,因为我的testfragment可以通过这种方式与任何类型的活动交互,前提是活动实现了我声明的接口。
另一方面,活动可以通过持有引用并调用其公共方法来与片段交互。这也是建议的将活动用作桥梁的分段到分段通信的方法。
这很酷,但有时感觉使用一个接口来实现这一点有点“过分”。
问题A
在这个场景中,我附加的片段有一个非常集中的角色,这意味着它们是为那个特定的活动而完成的,并且不会被其他的活动使用,忽略接口实现并做一些类似的事情在概念上是错误的吗?
((TestActivity) getActivity().myCustomMethod();
?
这也适用于这样的场景:我的活动必须处理各种各样的不同片段,这意味着它应该为它应该处理的每个片段实现一个方法。这使得代码陷入了“潜在不需要的行”的混乱。
进一步讲:仍然使用“聚焦”片段,目的是仅以某种方式工作,嵌套片段的使用是什么?
像这样添加它们
public class TestFragment extends Fragment {
private void myTestMethod() {
NestedFragment nested = new NestedFragment();
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, nested)
.commit();
}
}
这将NestedFragment绑定到TestFragment。我再说一遍,nestedfragment和testfragment一样,只能这样使用,否则就没有意义了。
回到问题上来,在这种情况下我该怎么做?
问题B
1)我是否应该在nestedfragment中提供一个接口,并使testfragments实现nestedfragment interface?在这种情况下,我将采取如下行动
嵌套片段
public class NestedFragment extends Fragment {
private NestedFragmentInterface listener;
public interface NestedFragmentInterface {
void actionMethodNested();
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (getParentFragment() instanceof NestedFragmentInterface) {
listener = (NestedFragmentInterface) getParentFragment();
}
// sending the event
if (listener != null) listener.actionMethodNested();
}
}
2)我应该(或者可以)忽略接口,只需调用
getParentFragment().publicParentMethod();
?
3)我是否应该在nestedfragment中创建接口,但让活动实现它,以便活动调用testfragment?
问题C
关于使用活动作为片段之间的桥梁的想法,我相信这是为了正确地处理所有这些对象的生命周期。在尝试手动处理系统可能抛出的异常时,是否仍然可以执行直接分段到分段(使用接口或直接调用公共方法)?
最佳答案
我会尽量把它弄清楚一点。
首先,考虑为片段设置侦听器的方法。在onviewcreated方法中设置listener是不好的,因为它会导致创建的任何片段都被过度重置listener。这足以将其设置为OnAtach方法。
我说过代码行。请注意,在您的应用程序中,最好将basefragment实现为设置fragmentlistener从资源创建视图。
除此之外,为了减少代码行并获得部分代码重用,可以在basefragment中使用泛型。所以请看下一段代码:
public abstract BaseFragment<T extends BaseFragmentListener> extends Fragment {
T mListener;
public void onAttach(Activity activity) {
super.onAttach(activity);
if (Activity instanceof T)
mListener = (T) activity;
}
abstract int getLayoutResourceId();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(getLayoutResourceId(), null);
// you can use some view injected tools here, mb ButterKnife
return layout;
}
}
回答A(对于问题A):
如果只有一个活动需要fragment来决定:“您真的需要在这里使用fragment吗?”。但是,最好有一个活动的片段,以便从活动中提取某些视图逻辑并清除基本逻辑。但要清除应用程序的基本架构逻辑,请使用侦听器。这将使其他开发人员的生活更轻松
答案B:
对于您需要解决的嵌套片段,它们需要使用精确的活动,或者只是片段,并将其用作到其他系统的桥梁。如果知道嵌套片段将一直嵌套,则需要将父片段声明为侦听器,否则必须使用其他方法。
注意:
作为在应用程序的diff部分之间进行通信的基本方法,您可以使用事件,也可以尝试查看事件总线。它为您提供了通用的通信方法,您可以提取调用监听器的自定义方法的逻辑,另外,所有逻辑都将位于处理事件中,并且您将拥有一个用于协作的中介系统。
答案C:
我部分地解释了片段之间协作的方法之一。使用一个事件分派器可以避免使用多个侦听器进行所有不同的通信。有时这是非常有益的。
或者我认为使用activity或activity中的其他类lives作为片段合作的中介更有用,因为在处理和系统的生命周期中存在许多片段变化的情况。它将所有这些逻辑集中在一个地方,使代码更加清晰。
希望我的考虑对你有帮助。