Android在Fragment之间传递数据

6
我有一个Activity和5个Fragment。在第一个Fragment中,用户输入电话号码。在最后(第五个)Fragment中,我需要显示这个电话号码,输入其他字段并将所有数据发送到服务器。对于每个Fragment,我都使用单独的Presenter(MVP)。
如何将数据从第一个Fragment传递到最后一个?
1)我不想通过所有的片段链来传递数据,因为它们不需要这个数据。
2)如果将这个数据存储在托管Activity中,则需要在Fragment类中调用((SomeActivity)getActivity()).getUserData()并将此数据传递给Presenter。
3)我选择了第三种方法。我创建了一个Singleton UserData类。这是一个简单的POJO类。我在第一个Fragment中创建UserData实例,设置所需的数据,然后在最后的Fragment中使用它来检索数据并添加缺失的字段。
但我不知道单例的做法是否正确。因为当用户进入另一个Activity时,我需要清除单例实例。是否有更好的解决方案?
编辑
我考虑过EventBus。但我需要从Fragment传递数据到Presenter。现在我在present中调用UserData.getInstance()并检索数据。我希望代码更加优雅而且正确。我想要听取更有经验的开发人员的意见,看看该使用什么方法。

你不能使用SharedPref吗? - Rohit Arya
@RohitArya 我认为这不是比将数据保存在Activity中更好的解决方案。我只需要这些数据发送到服务器,不需要长时间保存。 - Volodymyr
那么单例模式将是一个不错的选择。 - Rohit Arya
@0X0nosugar 我想要将逻辑和视图分离。如果我使用 SharedPref,那么我需要在 presenter 中使用 Context。现在通过 Singleton,我只需调用 getInstance。没有与 Context 相关的链接。 - Volodymyr
你可以使用应用程序级别的类来在你的片段之间存储和访问数据。 - Radhey
显示剩余4条评论
5个回答

2

有很多方法可以从一个类(包括Fragment)发送数据到另一个类。

考虑到Fragment的生命周期问题,你可以使用事件总线来实现这一点,而不会遇到任何麻烦。

class FragmentA {
    Bus bus;

    onCreate(){
      bus = new Bus();
    }

    @Subscribe public void receiveMessage(String message) {
       // TODO: Parse your message
    }

    onResume(){
      bus.register(this);
    }

    onPause(){
      bus.unregister(this);
    }
}

class FragmentB {

    onCreate(){
      bus.post("You have a message");
    }
}

更多关于集成otto的内容可以在这里找到。 当然还有很多其他选择。 https://greenrobot.github.io/EventBus/


我考虑过EventBus,但是我在我的问题评论中写了。我必须从“Fragment”传递数据到Presenter。现在我在Presenter内调用UserData.getInstance()并检索数据。我希望代码更加优雅且正确。 - Volodymyr
2
如果你有什么要补充的,请在你的问题中添加。你怎么期望别人能够阅读你的问题和评论并给出答案呢? - amalBit

2
我会按照模型视图控制器的方式来完成它。
class CustomerModel {
    String phoneNumber
}

interface ICustomerOwner {
    CustomerModel getCustomer()
}

class CustomerRegistrationWorkflowActivity extends Activity implements ICustomerOwner {
    CustomerModel getCustomer()
    ...
}

class CustomerContactDataFragment // fragment1 where you edit the phone number.

class CustomerRegistrationSummaryFragment // fragment5 showing all data plus submit button)

由于模型位于(CustomerRegistrationWorkflow)Activity中,因此片段可以通过调用与模型通信

((ICustomerOwner) getActivity()).getCustomer()

1
一种称之为优雅解决方案的方法使用事件总线,另一种则是老式的回调。 我的观点是要避免“片段链”的情况-当一个片段直接调用另一个片段时。 如果活动完全处理片段替换,则可以平等访问所有5个片段。 因此,它可以轻松地使用回调在它们之间传递数据。
在这种情况下,MVP没有任何问题。 Presenter使用回调将数据发送到其视图(片段)。 片段使用回调将数据发送到其活动。 然后,活动在片段管理器中找到第5个片段并更新/传递数据。
回调的情况似乎比事件总线更健壮,但仍然是品味问题。

0
我在传递数据到活动或片段方面遇到了很多问题。因此,我创建了DataCache,可以在任何地方传递任何对象。
这是一个超级简单的例子。Gihub : Android DataCache 发送者的片段
public class FragmentA {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        String msg = "the phone number"
        DataCache.getInstance().push(msg);
    }
}

接收器片段

public class FragmentB {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            String msg = DataCache.getInstance().pop(String.class);
        }
    }

试一下吧 :D 希望你能帮忙。


0

一个片段总是连接到包含它的活动中。因此,它可以轻松地与活动通信。使用您的活动作为通信渠道或通信媒介,您可以在附加到同一活动的片段之间创建通信链接。

连接到活动的片段可以通过getActivity()方法访问活动的实例,并且使用该实例,片段可以执行调用活动方法等任务。

现在,要将数据从一个片段传输到另一个片段,您可以在活动中创建方法,并通过该方法将一些数据存储在变量中。然后,在另一个片段中,您可以通过其他方法的帮助访问该变量的值。这里可以使用getter和setter方法的概念。

有关活动和片段通信的更多信息,请访问以下链接:http://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接