在一些延迟之后从另一个片段调用片段

时间:2013-10-11 14:08:32

标签: android fragment

我在网上搜索过,找不到如何从另一个片段调用片段的好参考。

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

3 个答案:

答案 0 :(得分:2)

嗯,首先你需要考虑从FragmentA到FragmentB的某种直接引用是一个非常糟糕的主意。原因:

  1. 可以重新创建FragmentB,您可以保留对FragmentB的旧引用的引用。所以你有内存泄漏。
  2. 可能无法创建,添加或显示FragmentB。所以你会有一个null /不可用的引用。
  3. 因此,您需要考虑基于从FragmentAFragmentB发送消息的方法。我看到了几个选项:

    • 使用FragmentA中的自定义操作发送广播消息FragmentB将自己注册为此类消息的接收者(在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中定义的某种界面,并在被请求时可以搜索是否可以找到{{1}如果是这样,请在那里调用一些方法。优点是您可以发送任何数据,无论其重量如何。基本构思在Android dev articles中有所描述。举例来说,您可以将FragmentB作为:

      公共类FragmentA扩展了Fragment {

      FragmentA

      }

    代理活动至少会包含以下方法和签名:

    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
    • 使用或实施某种事件总线。一些general details here。对于Android,我记得Otto事件总线非常方便易用。这是a link。这与第一个选项非常相似,因为您无论如何都需要注册和取消注册。

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

    享受编程!

答案 1 :(得分:1)

片段不应该直接相互连接,这可能是你找到一个体面的指南来解决这个问题。

您的方法假设片段B始终可以到达(并准备好)以使片段A进行交互,而实际上并非如此,将会破坏片段的灵活性,并在将来导致问题。

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

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

上面的Android指南,特别是针对上一个主题,向您展示了如何执行此操作。

答案 2 :(得分: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);