【问题标题】:Adding a listener between two fragments在两个片段之间添加监听器
【发布时间】:2023-03-09 23:57:01
【问题描述】:

假设我有两个片段,A 和 B,其中 B 包含一个列表。我想在片段 B 上添加一个侦听器,通知片段 A 所选列表项。我无法弄清楚如何在片段 B 中初始化监听器,因为在片段的构造函数中传递参数是不好的做法。

注意:片段 B 包含在片段 A 中。即我在片段 A 中有一个 FrameLayout; Fragment B 覆盖了 FrameLayout。

知道我该怎么做吗?

【问题讨论】:

  • 不是数据,接口中的监听器。
  • 你也可以试试事件总线库,它应该可以简化通信。但是@JPal 提出的解决方案应该可行,这是一种更标准的方式。

标签: android android-fragments android-recyclerview listeners


【解决方案1】:

如果您说 Fragment B 是 Fragment A 的子 Fragment(也就是说,您已使用 Fragment A 的 getChildFragmentManager() 将其添加到 Fragment A),那么您可以使用与 @ 相同的方法987654322@ 接口,但使用getParentFragment() 而不是getActivity()

例如:

片段 B:

@Override
public void onAttach(Context context) {
    MyInterface myInterface = (MyInterface) getParentFragment();
}

假设片段 A 实现了MyInterface

我们用来避免必须知道 Fragment 是由另一个 Fragment 托管还是由 Activity 托管的一种便捷方法如下:

public static <T> getInterface(Class<T> interfaceClass, Fragment thisFragment) {
    final Fragment parent = thisFragment.getParentFragment();
    if (parent != null && interfaceClass.isAssignableFrom(parent)) {
        return interfaceClass.cast(parent);
    }

    final Activity activity = thisFragment.getActivity();
    if (activity != null && interfaceClass.isAssignableFrom(activity)) {
        return interfaceClass.cast(activity);
    }

    return null;
}

然后你可以使用:

MyInterface myInterface = getInterface(MyInterface.class, this);

无论 Fragment B 是作为子 Fragment 托管还是直接托管在 Activity 中都没有关系。

【讨论】:

  • 这似乎可以满足我的需求,但我没有使用getChildFragmentManager(),所以我会研究它并尝试它,谢谢!
  • 这个答案太棒了,这应该是投票最多的答案,因为它允许在没有活动规则的情况下直接交流
  • 很棒的答案!
【解决方案2】:

对于这种情况,更好的方法是使用接口,因为您想要做的是片段之间的通信。您想在 B 更改时通知 A。这应该通过父活动来完成。这是有关该主题的 android 文档:https://developer.android.com/training/basics/fragments/communicating.html

它的要点是你想用一个名为 OnItemSelected 的方法定义一个接口(你可以随意命名它)。在 B 中,您需要对此接口的引用。选择项目后,调用新的 OnItemSelected 方法。在两个fragment的父activity中实现这个接口。在实现中,你可以放任何你想修改的代码。

一个例子

通讯接口

public interface CommunicationInterface {
    public void onItemSelected(int position);
}

片段B

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    CommunicationInterface myInterface = (CommunicationInterface) getActivity();
    // What ever else you want here
}

@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    // Send the event to the host activity
    myInterface.onItemSelected(position);
}

MainActivity

public class MainActivity extends FragmentActivity implements CommunicationInterface {
    // What ever other code you have

    @Override
    public void onItemSelected(int position) {
        FragmentA fragA = (FragmentA)
        getSupportFragmentManager().findFragmentById(R.id.fragment_a);

        // Code to interact with Fragment A
    }

【讨论】:

  • 是的,我已经看到并尝试过了。但问题是在我的情况下,片段 B 在片段 A 中,稍后我会有更多片段,所以从主要活动中实现所有接口很麻烦,这就是我正在寻找一种新方法的原因.
【解决方案3】:

查看合约模式https://gist.github.com/JakeWharton/2621173

如果您使用多个片段,则不必为每个片段都这样做,如果有的话,只需将其添加到您的 BaseActivity。

这个例子展示了activity和fragment之间的通信。但是对于嵌套片段,您可以将活动替换为 getParentFragment();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    • 1970-01-01
    • 2016-02-04
    • 2014-08-07
    • 1970-01-01
    相关资源
    最近更新 更多