我在我的应用中使用导航抽屉。我有一个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配合得很好。但是,当所有碎片都是碎片时,我怎么能管理呢。
答案 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
中的一个示例,它提供了一个很好的解决方案,您的片段无论数量多少,彼此都不了解,但是您仍然可以创建一个简单而优雅的机制,无需费力即可使用。
答案基于ViewModels和LiveData。
注意:如果您对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可以继续正常工作。