【问题标题】:Fragment to Fragment communication - why is the interface really necessary?片段到片段的通信——为什么接口真的是必要的?
【发布时间】:2016-09-17 14:59:01
【问题描述】:

这里是初学者。

据我了解,片段应通过其托管活动相互通信,以在其他情况下保持独立和可重用。

我读到应该通过在片段中声明接口并在活动中实现它们来完成。 这是“仅仅”处理它的最佳方式吗,因为您可以确保 Activity 已为该通信做好准备(它确实具有处理该通信的方法)?

由于我很难围绕接口(以及 java/android 中的许多其他东西,就此而言),这可以在没有接口的情况下完成吗?我可以在片段中获取对托管活动的引用并调用该活动的方法吗?

(片段类)

Activity activity = getActivity();

activity.doThatThingToOtherFrag(String myString);

(活动类)

Fragment otherFragment = getSupportFragmentManager().findFragmentById(R.id.myOtherFrag);

public void doThatThingToOtherFrag(String string) {
//do something to myOtherFrag
}

或者在这种情况下我没有得到关于实现接口的其他内容?

* 编辑 *

假设我在另一个活动中重用了该片段。只要该活动还具有 doThatThingToOtherFrag(String myString) 方法,我就可以通过 getActivity() 获取对它的引用,并且仍然调用 activity.doThatThingToOtherFrag( String myString) 来自我的片段,对吧?我不需要更改我的片段代码中的任何内容——还是我在这里遗漏了什么?

我想我的问题应该是:那里的接口是否只是为了确保/任何托管活动实现 doThatThingToOtherFrag 方法?或者在这种情况下还有什么我不知道的接口吗?感谢您的帮助!

【问题讨论】:

  • 好吧,你错过了它不是Activity而是MyActivity的事实,你的方法调用更像((MyActivity)activity).doThatThing ..换句话说,因为doThatThing属于MyActivity您将不得不将哪些紧密耦合到 MyActivity。
  • ...要重用,您每次都必须更改此演员表,除非您对接口进行编程。如果您总是在处理 Activity(而不是子类),那么接口没有意义,但它假定 doThatThing 是您编写的方法,而不是已经属于您的 Activity 基类的东西。跨度>
  • 我认为我可以将任何 Activity 子类(例如 FragmentActivity)简单地转换为 (Activity) 并且只要有 doThatThing 方法,我就不必更改片段中的任何内容代码。
  • 当然,但在这种情况下,您正在向上转换 - 向上转换为基类。通常,您从 Activity 扩展并在那里实现一些东西 - 要使用您添加到 MyActivity 的方法,您需要向下转换(这不是一个好习惯)。
  • 一个不涉及强制转换的示例...假设您的片段有一个方法setMyActivity( MyActivity activity ) 其中MyActivity 基本上是您的应用程序(并扩展了Activity)。现在假设您添加了一个新活动MyActivity2,并且您也想在那里使用您的片段 - 哎呀,您需要重写您的setMyActivity 方法来传递MyActivity2。很不方便。

标签: java android android-fragments


【解决方案1】:

“编程到界面。”是面向对象编程的普遍准则。您当然可以直接与活动进行通信,而无需使用界面。但是,这会在片段和活动之间产生紧密耦合。

假设您希望在两个不同的活动中重复使用相同的片段。使用接口可以灵活地执行此操作。

回答编辑:

只要该活动还具有 doThatThingToOtherFrag(String myString) 方法,我就可以通过 getActivity() 获取对它的引用,并且仍然从我的片段中调用 activity.doThatThingToOtherFrag(String myString) ,对吗?

我假设你的意思是这样的:

Activity activity = getActivity();
activity.doThatThingToOtherFrag(String myString);

这不会编译,因为Activity 没有名为doThatThingToOtherFrag() 的方法。但是,如果你这样做

FragmentCommunicationInterface activity = (FragmentCommunicationInterface) getActivity();
activity.doThatThingToOtherFrag(String myString);

现在它将编译。这还有另一个问题:如果将调用它的片段添加到 实现 FragmentCommunicationInterfaceActivity 会怎样。现在你在做这个案例时会得到一个运行时错误。

一种可能的解决方案是将FragmentCommunicationInterface 作为片段构造函数的参数:

public class MyFragment extends Fragment {
    private FragmentCommunicationInterface communication;

    public MyFragment(FragmentCommunicationInterface communication) {
        this.communication = communication;
    }
}

现在你用

创建一个片段
MyFragment frag = new MyFragment(this);

使用接口的另一个优点是接口可以由任何类实现,而不仅仅是扩展Activity 的类。这比我上面暗示的更灵活。它允许您以任何您想要的方式组织代码以与活动或其他片段进行通信。

【讨论】:

  • 该接口是否仅用作保证 Activity 已实现 doThatThingToOtherFrag 方法的一种方式,还是有我仍然不知道的原因?如果可能,请阅读我的编辑。谢谢!
  • @bernardo.g 这是原因之一。有关您自己的编辑的详细信息,请参阅我的编辑。
【解决方案2】:

这不是真的必要的,但它可能是可取的。

通常,接口帮助代码不依赖于您调用其代码的类。您并不真正关心您正在调用哪个 Fragment 类,您真正关心的是无论您在调用什么,它都需要具有doThisOrThat() 的能力——这就是您在界面中放入的内容。

这种解耦实际上是关于帮助使用多态性。假设您的代码可能使用两个 Fragment 类,而您现在使用一个,并且两者都可以doThisOrThat()。在这种情况下,使用接口将帮助您编写更简洁的代码,因为您不需要编写重复的代码来调用相同的方法,除非更改您将其转换为的内容。

无论如何,为了真正解耦你的类,你可能想了解 EventBus(不管哪种实现)。

【讨论】:

  • 我最近听说过 EventBus,我一直想去看看。谢谢!
【解决方案3】:

通过这种方式,您可以使您的片段与任何实现该接口的活动一起工作。这完全增加了您在问题中指出的独立性和可重用性。

如果您使用活动类的方法进行“通信”,您将无法使其工作(与)其他活动,因为它们属于不同的类。

【讨论】:

  • 你能看看我的编辑吗?它不适合这里。
  • 要从片段中调用的方法必须在类中或在运行时由类实现的接口中定义,以便正确链接。请记住:在 Java 中,运行时名称不存在;它们被转换为符号,因此必须严格定义。
  • 也就是说:两个同名方法在运行时会有不同的符号。
  • 哦,我想我可以让 Android 查看任何 Activity 并使用名为 doThatThingToOtherFrag 的方法,只要该方法在那里实现即可。
  • 这就是接口的全部意义:它们保证某些方法被实现,以便实现接口的类可以被接口。
【解决方案4】:

不采用上述实现方式的一个很好的理由是松散耦合。创建设计良好的软件是一种程序设计模式。我不会在这里创建一个新的讨论,因为 StackOverflow 中还有很多其他讨论。

What is "loose coupling?" Please provide examples

请花点时间理解这个概念,因为这将为您节省大量程序员的时间。

干杯!

【讨论】:

    【解决方案5】:

    接口最适合通信两个片段、两个活动或与任何类通信,因为接口在其他人想要通信时同时触发。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多