活动和片段交互

Jas*_*sby 13 oop android listener android-fragments

我有一个Activity多个Fragments.我想从其中一个中显示DialogFragment或打开另一个.我知道应该是开放s的任务,所以我尝试了几件事.FragmentFragmentActivityFragment

首先,
我尝试使用getActivity()并转换它,以便我可以调用一个方法Activity来显示一个Fragment但是这会在Fragmentwith中创建一个依赖项,Activity并且我希望尽可能避免添加依赖项.

第二次
接下来我尝试了一个听众通知Activity它应该显示一个Fragment.所以我在Activity实现监听器接口时创建了一个类.但是我遇到了问题,因为我必须使用New MyActivity().new Listener();它会Exception在我尝试使用时抛出一个,getSupportFragmentManager()因为这个实例Activity没有初始化.

第三
我又试图有Activity直接实现侦听器,因为那时我只是用侦听器而不是Activity创建依赖.然而,现在我已经到了这样的程度,我Activity将实施2-4个不同的界面,这让我犹豫不决,因为它会严重降低凝聚力.

所以我试过的任何方式我似乎都碰到了一堵砖墙并创造了依赖性,我不确定我是否需要创造.我搞砸了,不得不选择其中一种选择吗?如果是这样哪个选项最好?非常感谢任何帮助或建议.

Can*_*mas 11

我个人会说片段应该被认为是可重复使用的模块化组件.因此,为了提供这种可重用性,片段不应该对其父活动有太多了解.但作为回报,活动必须知道他们持有的碎片.

所以,在我看来,第一个选项永远不应该考虑你提到的导致高度耦合代码的依赖性原因.

关于第二个选项,片段可以委托任何应用程序流或UI相关决策(显示新片段,决定在触发片段特定事件时要执行的操作等等)到其父活动.因此,您的侦听器/回调应该是特定于片段的,因此它们应该以片段形式声明.持有这些片段的活动应该实现这些接口并决定做什么.

所以对我来说第三种选择更有意义.我相信,就他们持有的特定回调而言,活动更具可读性.但是,你是对的,你的活动可能成为一个神的对象.

如果您不想实现多个接口,也许可以检查Square的Otto项目.它基本上是一个事件总线.


Hit*_*ahu 10

创建界面

public interface ListenFromActivity {
    void doSomethingInFragment();
}
Run Code Online (Sandbox Code Playgroud)

Activity类中保持对ListenFromActivity接口的引用

 public ListenFromActivity activityListener;   
Run Code Online (Sandbox Code Playgroud)

使公共方法设置监听器

 public void setActivityListener(ListenFromActivity activityListener) {
        this.activityListener = activityListener;
    }
Run Code Online (Sandbox Code Playgroud)

在活动类中添加一些触发点,这里我使用了用户交互

    @Override
    public void onUserInteraction() {
        super.onUserInteraction();

        if (null != activityListener) {
            activityListener.doSomethingInFragment();
        }
    }
Run Code Online (Sandbox Code Playgroud)

现在在Fragment类中

使你的片段实现接口类

public class SomeFragment extends Fragment implements ListenFromActivity
Run Code Online (Sandbox Code Playgroud)

Android studio会提示你在片段中实现接口的方法

 void doSomethingInFragment()
{//Add your code here 
}
Run Code Online (Sandbox Code Playgroud)

最终的部分部分监听器实例在片段onCreate方法中这样的活动

((ListnerActivity) getActivity()).setActivityListener(SomeFragment.this);
Run Code Online (Sandbox Code Playgroud)

DONE!.现在你可以从activity调用fragment方法了.