【问题标题】:How to send data of three fragments to single activity?如何将三个片段的数据发送到单个活动?
【发布时间】:2019-10-24 06:46:54
【问题描述】:

我有一个更简单的问题,但我在互联网上找不到有关它的答案。这是交易:我有三个片段,我需要将每个片段的数据发送到单个活动,然后打开另一个活动。我打算使用一个界面来做到这一点。那么,我需要为每个片段创建三个接口并在活动中实现它们吗?我有三个实现为每个活动获取数据?在编写代码之前,我需要了解它。提前致谢。

Demo image

【问题讨论】:

  • 除了接口,您可以创建一个单例数据持有者类使用ViewModel
  • @Taseer Ahmad。 viewModel 对于我想做的事情是不切实际的?它们是为托管它们的单个父活动管理的 5 个片段。图片在上面的描述。
  • ViewModel 并不是一种不切实际的方法,但是,如果您不想添加它的依赖并且您发送的数据很小,我建议您使用接口。您不需要创建三个不同的接口。下面提供的答案如何对您没有帮助?你有什么不明白的?
  • @Tasser Ahmad。我不明白如何从三个片段中获取数据并将其设置为活动。我应该在哪里执行或实例。我是否必须在每个片段上实现接口类的方法并在活动中调用它们的对象或在活动中实现接口?我想获取每个片段的整数数据来托管容器活动。
  • 我可以为您提供一个示例“通用”代码,以便您自己实现它,但它在 Kotlin 中

标签: java android interface fragment


【解决方案1】:

首先,让我们创建一个interface

interface MyInterface {
     fun onSomethingDone(someData: Int)  //A sample function, you can customize it your needs.
 }

那么

像这样在您的活动中覆盖onAttachFragment。永远记住这条规则,永远不要将片段与活动紧密耦合。因此,您可以做的是检查片段并进行相关操作,如下所示:

class MyActivity : AppCompatActivity() {

    override onAttachFragment(fragment: Fragment) {

           when (fragment) { //A switch statement, checking using instanceOf() in Java.
             is Fragment1 -> fragment.firstFragmentListener = this //Proviving context of your activity to public variable of each fragment.
             is Fragment2 -> fragment.secondFragmentListener = this
             is Fragment3 -> fragment.thirdFragmentListener = this
         }
     }
 }

这将确保您不会像在设置自定义侦听器时将片段强制转换为特定活动的上下文那样紧密耦合片段。

让我们转到片段

 class Fragment1 : Fragment() {

     var firstFragmentListener: MyInterface? =  null  //public member, we are accessing it in our activity method, look above! 

      override onCreate() {

          myButton.setOnClickListener {
              firstFragmentListener.onSomethingDone(999) // Just sending random integer as the method parameter.
           }
       }
  }

这个示例片段类应该让您充分了解它是如何设置的。就像这个片段类的实现方式一样,您可以对 Fragment2 和 Fragment3 执行相同的操作。

回到我们的活动

但这一次,我们将实现一个监听器方法。

class MyActivity : AppCompatActivity(), MyInterface {

   override fun onSomethingDone(someData: Int) {
      when (someData) {
         999 -> //Came from first fragment
         1000 -> //Second fragment
         1001 -> //Third fragment
      }
    }

    override onAttachFragment(fragment: Fragment) {

           when (fragment) { //A switch statement, checking using instanceOf() in Java.
             is Fragment1 -> firstFragmentListener = this //Proviving context of your activity to public variable of each fragment.
             is Fragment2 -> secondFragmentListener = this
             is Fragment3 -> thirdFragmentListener = this
         }
     }
 }

就是这样,我会连接一个链接给你一个疯狂的想法。 Single interface for multiple fragments。而ViewModel 是第二代 Android 开发的一部分,它提供了各种优势,而不仅仅是片段和活动之间的相互通信。

【讨论】:

  • is Fragment1 -> fragment.firstFragmentListener = this 如何在java中做到这一点?我应该为 Fragment1 中的侦听器创建一个 getter 方法吗?
  • if (fragment instanceOf Fragment1)。您需要使用instanceOf 关键字。由于Fragment1 中的侦听器是公共的,因此您无需创建 getter setter,因为它们对私有成员有意义。
  • 我应该覆盖onDetach 方法并生成firstFragmentListener = null,否则不会有任何区别。
  • @IbrahimAbousalem 不需要,因为片段与您的类相关联,一旦活动超出范围,所有内容都将自动清理。此外,这些监听器非常轻量级,您可以忽略它们。您可以使它们为空,但不要指望会发生任何好事。请阅读this
  • 非常感谢 Taseer Ahmad。在每个片段中,我声明了接口类型的对象并覆盖了“onAttach”。在父活动中,我实现了接口。放置参数,例如(int,tag),并在每个标签中检查“switch case”,我做了将这些数据存储在活动的局部变量中的操作。由于我需要返回值才能在其他操作中使用,因此我针对每种情况进行了解析,将这些数据存储在父活动的局部变量中。现在我将使用这些值来替换其他片段。
【解决方案2】:

您可以通过New > Java Class 创建一个单独的界面,然后在对话框中选择Kind > Interface。 然后你将你需要的方法添加到接口并让你的活动实现它。这样做之后,您将转到 Fragments 并在 onAttach(Context context) 方法中获取该接口的实例,如下所示:

    @Override
    public void onAttach(@NonNull Context context)
    {
        Log.d(TAG, "onAttach:true");

        super.onAttach(context);

        if (context instanceof OnFragmentInteractionListener)
        {
            mFragmentInteractionListener = (OnFragmentInteractionListener) context;
        }
        else
        {
            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
        }
    }

例如,现在您可以通过在 Fragment 类中的任何位置说 mFragmentInteractionListener.deleteInternet(true) 来调用接口方法。

如果您还有其他问题,请在 cmets 中告诉我。

【讨论】:

  • 哦,谢谢勒内。但我是一个小新手,那怎么样。我有三个片段:A、B、C。每个片段都有不同的结果:结果 A、结果 B 和结果 C。我需要这些片段将数据发送到父活动,并且根据结果,此活动将打开另一个片段 D 或E. 所以,这就是我有一个问题的原因:我是否必须为每个片段创建例如“mFragmentInteractionListener”并在活动中实现它们?我已经阅读了很多,但我找不到任何与将多个片段的数据发送到活动相关的内容。
  • 给我更多关于那个的信息。您需要将哪些信息从每个片段传递给您的底层活动?
  • 我需要发送三个和整数的结果。这是交易:int sum1 (fragment1)、int sum2 (fragment2) 和 int sum3 (fragment 3) 到活动。我在 Internet 上找到的示例是使用内部带有接口的单个​​片段。但是正如您所说,最好单独创建接口类并获取每个类的结果。
  • 您的活动如何处理片段输出?它需要知道它来自哪个片段吗?
  • 我的活动在一个容器内包含 3 个片段(动态)。一个片段替换同一活动中的另一个片段。我需要捕获每个的总和并发送给它们的父活动
猜你喜欢
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 2020-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多