将数据从当前片段传回到先前的片段

时间:2017-03-10 06:16:34

标签: android android-fragments fragment fragmentmanager

我在我的应用中使用导航抽屉。我有一个MainActivity,其余的是片段。所以问题是假设我有三个片段,如A,B,C。

现在在A我有一个按钮,我从A> B发送数据 例如putSring(“datafrom A”,“data from A”);
现在在B我收到来自A的数据。
我在B中有一个按钮,我从B> C发送数据 例如putSring(“datafrom B”,“data from B”);
现在在C中我从B接收数据。
然后,我在C中有一个Button,并从C> B发送数据 例如putSring(“data from C”,“data from C”);

所以,似乎在B中我从两个不同的片段中获取数据。我尝试了所有使用活动,它与startActivityforresult配合得很好。但是,当所有碎片都是碎片时,我怎么能管理呢。

3 个答案:

答案 0 :(得分:47)

从B启动片段C时,可以调用setTargetFragment()。示例:

FragmentC fragmentC = FragmentC.newInstance();
fragmentC.setTargetFragment(FragmentB.this, REQUEST_CODE);
getFragmentManager().beginTransaction().replace(R.id.container, fragmentC).commit();

然后当你想从C传递数据回到片段B时,你可以调用以下代码:

getTargetFragment().onActivityResult(
                getTargetRequestCode(),
                Activity.RESULT_OK,
                new Intent().putExtra("datafrom C", "datafrom C")
);

从片段B中的onActivityResult()方法获取它:

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode==REQUEST_CODE && resultCode==Activity.RESULT_OK) {
        String datafromC = data.getStringExtra("datafrom C");   
    }
}

答案 1 :(得分:4)

当您将数据从片段A发送到片段B时,请使用与下面相同的布尔值: -

FragmentA - > FragmentB

FragmentB ldf = new FragmentB ();
Bundle args = new Bundle();
args.putBoolean("BOOLEAN_VALUE",true);
ldf.setArguments(args);

getFragmentManager().beginTransaction().add(R.id.container, ldf).commit();

当你从Fragment C向Fragment B发送数据时,使用在片段A到B中使用的相同BOOLEAN,如下所示 -

FragmentC - > FragmentB

FragmentB ldf = new FragmentB ();
    Bundle args = new Bundle();
    args.putBoolean("BOOLEAN_VALUE",false);
    ldf.setArguments(args);

    getFragmentManager().beginTransaction().add(R.id.container, ldf).commit();

在最后我们必须检查在FragmentB中接收的值是否来自Fragment A OR FragemntC

<强> FragmentB

   Boolean getValue= getArguments().getBoolean("BOOLEAN_VALUE");  
   if(getValue)
   {
    //VALUE RECEIVED FROM FRAGMENT A
   }
   else
   {
   //VALUE RECEIVED FROM FRAGMENT C
   }

答案 2 :(得分:2)

自2017年以来,情况发生了很大变化。我发布的答案基本上是https://developer.android.com中的一个示例,它提供了一个很好的解决方案,您的片段无论数量多少,彼此都不了解,但是您仍然可以创建一个简单而优雅的机制,无需费力即可使用。

答案基于ViewModelsLiveData

注意:如果您对Architecture Components不熟悉,我强烈建议您在任何时候都尽可能多地了解它,因为它将提高生产速度并减少错误的数量。您的项目。

以下所有内容均来自以下链接: source (Kotlin/Java)

在片段之间共享数据

一个活动中两个或多个片段通常需要 互相交流。想象一个常见的主从案例 片段,其中有一个片段,用户可以在其中选择一个项目 从列表和另一个片段中显示 选择的项目。这种情况永远都不是小事,因为两个片段都需要 定义一些接口描述,并且所有者活动必须绑定 两者在一起。此外,两个片段都必须处理该场景 另一个片段尚未创建或不可见的地方。

可以使用ViewModel对象解决此常见的痛点。 这些片段可以使用其活动范围共享ViewModel 处理此通信,如以下示例所示 代码:

class SharedViewModel : ViewModel() {
    val selected = MutableLiveData<Item>()

    fun select(item: Item) {
        selected.value = item
    }
}

class MasterFragment : Fragment() {

    private lateinit var itemSelector: Selector

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        itemSelector.setOnClickListener { item ->
            // Update the UI
        }
    }
}

class DetailFragment : Fragment() {

    // Use the 'by activityViewModels()' Kotlin property delegate
    // from the fragment-ktx artifact
    private val model: SharedViewModel by activityViewModels()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model.selected.observe(viewLifecycleOwner, Observer<Item> { item ->
            // Update the UI
        })
    }
}

请注意,两个片段都检索包含它们的活动。 这样,当每个片段都获得ViewModelProvider时,它们 接收相同的SharedViewModel实例,其范围仅限于此 活动。

此方法具有以下优点:

  • 该活动无需执行任何操作或对此一无所知 通讯。
  • 片段不需要彼此了解 SharedViewModel合同。如果碎片之一消失,则 另一个人照常工作。
  • 每个片段都有自己的生命周期, 并且不受另一个生命周期的影响。如果一个片段 替换另一个,UI可以继续正常工作。