0

我搜索了整个网络,找不到关于如何从另一个片段调用片段的好的参考。

Fragment A -> Fragment B(片段 A 3 秒后调用片段 B)

4

3 回答 3

2

嗯,首先你需要考虑的是,以某种方式保持从 FragmentA 到 FragmentB 的直接引用是一个非常糟糕的主意。为什么:

  1. FragmentB 可能会被重新创建,并且您可以保留对 FragmentB 的旧引用的引用。所以你有内存泄漏。
  2. FragmentB 可能无法创建、添加或可见。所以你会有一个空/不可用的参考。

出于这个原因,您需要考虑基于从FragmentAto发送消息的方法FragmentB。我看到几个选项:

  • 使用来自 的自定义操作发送广播消息FragmentAFragmentB将自己注册为此类消息的接收者(在 onCreate/onResume/onAttach 中并在 onDestroy/onPause/onDetach 中取消注册)并且当消息到达时它可以处理它。如果您没有要发送的数据,FragmentA或者FragmentB如果您这样做是原始类型或易于实现,这非常适合Parcelables。这是一个例子:

有这个FragmentA

private void sendMessageToFragmentB(String someData) {
    Intent messageIntent = new Intent("com.your_package.A_TO_B_ACTION");
    messageIntent.putExtra("DATA_VALUE", someData);
    LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(messageIntent);
}

虽然在FragmentB你可以有这个:

public class FragmentB extends Fragment {
    private BroadcastReceiver messagesFromAReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            if ("com.your_package.A_TO_B_ACTION".equals(intent.getAction())) {
                String dataFromA = intent.getStringExtra("DATA_VALUE");
                dataFromAReceived(dataFromA);
            }
        }
    };

    protected void dataFromAReceived(String data) {
        // here you have the data
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        IntentFilter messageFromAIntentFilter = new IntentFilter("com.your_package.A_TO_B_ACTION");
        LocalBroadcastManager.getInstance(getActivity()).registerReceiver(messagesFromAReceiver,
                messageFromAIntentFilter);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(messagesFromAReceiver);
    }

}
  • 使用宿主活动作为代理:宿主活动实现了某种定义的接口FragmentA,当被请求时,它可以搜索是否可以找到FragmentB,如果可以,则调用其中的某个方法。优点是您可以发送任何数据,无论其重量如何。基本思想在Android 开发文章中有所描述。举例来说,你可以有FragmentA

    公共类 FragmentA 扩展 Fragment {

    public static interface CallerProxy {
        public void sendCustomMessage(Object... dataParams);
    }
    
    private CallerProxy proxyActivity;
    
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (activity instanceof CallerProxy) {
            this.proxyActivity = (CallerProxy) activity;
        }
    }
    
    @Override
    public void onDetach() {
        super.onDetach();
        this.proxyActivity = null;
    }
    
    private void sendMessageToFragmentB(String someData) {
        if (proxyActivity != null) {
            // send whatever data
            proxyActivity.sendCustomMessage(new Integer(1), new Object());
            // or don't send anything ...
            proxyActivity.sendCustomMessage();
        }
    }
    

    }

代理活动将至少具有以下方法和签名:

public class MyProxyActivity extends FragmentActivity implements CallerProxy {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // call setContentView and then make sure you've added FragmentA and
        // FragmentB.

    }

    @Override
    public void sendCustomMessage(Object... dataParams) {
        // FragmentB must be identified somehow, either by tag,
        // either by id. Suppose you'll identify by tag. This means you've added
        // it previously with this tag
        Fragment fragment = getSupportFragmentManager().findFragmentByTag("FragmentB-TAG");
        if (fragment != null) {
            FragmentB fragB = (FragmentB) fragment;
            fragB.dataFromAReceived(dataParams);
        }
    }
}

虽然FragmentB您只需要一个可以使用上述发送参数调用的方法:

public void dataFromAReceived(Object ... data) {
    // here you have the data
}
  • 使用或实现某种事件总线。这里有一些一般细节。对于 Android,我记得Otto事件总线非常方便且易于使用。这是一个链接。这与第一个选项非常相似,因为无论如何您都需要注册和取消注册。

最后,这取决于您需要作为消息发送什么,何时应该接收它以及它需要有多灵活。... 你的选择!

享受编程!

于 2013-10-11T15:07:39.730 回答
1

片段不应该直接相互连接,这可能是您在寻找合适的指南时遇到的问题。

您的方法假设片段 B 始终可以访问(并准备好)片段 A 进行交互,这实际上是不正确的,这会破坏片段的灵活性,并会在未来给您带来问题。

片段交互的更好方法是仅通过直接与活动对话的接口进行对话,该活动可以处理谁在何时何地还活着,应该接收什么。

-> http://developer.android.com/training/basics/fragments/index.html

上面的这个 Android 指南,特别是最后一个主题,向您展示了如何做到这一点。

于 2013-10-11T15:08:03.850 回答
0

我希望这段代码对你有帮助..

在您的第一个片段中添加此代码

onCreateView

LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getActivity());

    IntentFilter intentFilter = new IntentFilter("update");
    // Here you can add additional actions which then would be received by the BroadcastReceiver

    broadcastManager.registerReceiver(receiver, intentFilter);



@Override
public void onDestroyView() {
    LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(receiver);
    super.onDestroyView();
}

private BroadcastReceiver receiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if (action != null && action.equals("update")) {
            // perform your update
            getOngoingOrderData();
        }

    }
};

在您的第二个片段中添加此代码您发送广播..

 Intent intent = new Intent("update");

                        LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(getActivity());
                        broadcastManager.sendBroadcast(intent);
于 2016-09-21T11:26:34.463 回答