如何从一个片段传递数据到前一个片段?

25

我正在从FragmentA转到FragmentB。现在我想要从FragmentB传递数据到FragmentA。那么我该怎么做呢?

目前,我正在使用getCustomFragmentManager().popBackStack();从FragmentB返回到FragmentA,但没有传递任何值。


可能是将数据发送到堆栈中的前一个片段的重复问题。 - juliano.net
请查看此链接:https://dev59.com/NY7ea4cB1Zd3GeqPG-H8#32880451,可能会有用。 - Ankita Shah
使用接口或广播接收器。 - kalpana c
你想如何传递值?我的意思是当FragmentB被销毁或仍然可见时。 - Mithun Sarker Shuvro
FragmentB已被销毁。 - Shweta Chauhan
可能是如何将第二个片段的结果传递给第一个片段的重复问题。 - Bö macht Blau
5个回答

52

在 FragmentA 中

    FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction();
    FragmentB frgamentB = new FrgamentB();
    fragmentB.setTargetFragment(FrgamentA.this, AppConstant.FRAGMENT_CODE);
    ft.addToBackStack(fragment.getClass().getName());
    ft.add(R.id.content, fragment, tag);
    ft.commit();

现在在FragmentA中重写onActivityResult()

public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_OK) {
      if (requestCode==AppConstant.FRAGMENT_CODE){
         int addID = data.getIntExtra("addressID", 0);
         String addressLine=data.getStringExtra("addressLine");
      }
    }
}

在FragmentB中(点击返回按钮时)

Intent intent = new Intent(context, FragmentB.class);
intent.putExtra("addressID", list.get(position).getId());
intent.putExtra("addressLine", list.get(position).getAddressLine1());
getTargetFragment().onActivityResult(getTargetRequestCode(), RESULT_OK, intent);
getFragmentManager().popBackStack();

在 Kotlin 中的更新

Fragment 扩展

fun Fragment.addFragment(fragment: Fragment,targetFragment: Fragment,requestCode: Int, isAddToBackStack: Boolean = false, init: Bundle.() -> Unit = {}) {
    requireFragmentManager().inTransaction {
        val bundle = Bundle()
        bundle.init()
        fragment.arguments = bundle
        setTargetFragment(targetFragment,requestCode)
        if (isAddToBackStack) {
            addToBackStack(fragment::class.java.simpleName)
        }
        add(R.id.content, fragment, fragment::class.java.simpleName)
    }
}


inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> Unit) {
        val fragmentTransaction = beginTransaction()
        fragmentTransaction.func()
        fragmentTransaction.commit()
    }

fun Fragment.removeFragment(fragment: Fragment, enter: Int = 0, exit: Int = 0) {
    requireFragmentManager().inTransaction {
        remove(fragment)
    }
}

在 FragmentA 中

addFragment(FrgamentB(),this,AppConstant.FRAGMENT_CODE,true)

现在在FragmentA中覆盖(onOverride) onActivityResult()方法

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == FRAGMENT_CODE && resultCode == Activity.RESULT_OK) {
            val addID = data?.getIntExtra("addressID", 0)
            val addressLine = data?.getStringExtra("addressLine")
        }
 }

在 FragmentB 中(点击返回按钮时)

val intent = Intent(context, FragmentB::class.java)
intent.putExtra("addressID", list.get(position).getId()) 
intent.putExtra("addressLine",list.get(position).getAddressLine1())                
targetFragment.onActivityResult(targetRequestCode,RESULT_OK, intent)
fragmentManager.popBackStack()

在FragmentA的最后一行忘记添加ft.commit();。 - B.shruti
"AppConstant" 是从哪里来的? - Jakob
@Jakob:这只是静态代码。您可以使用任何代码。我将该代码放在一个AppConstant类中。 - Shweta Chauhan

6
如果使用Kotlin和Android Navigation Architecture,您可以像这样使用从Navigation 2.3.0-alpha02版本发布的此方法

在Fragment B上设置结果:

findNavController().previousBackStackEntry?.savedStateHandle?.set("key", result)

观察具有相同键的 Fragment A 的结果:

    findNavController().currentBackStackEntry?.savedStateHandle?.getLiveData<Type>("key")?.observe(
    viewLifecycleOwner) {result ->
    // Do something with the result.
}

在B片段中使用onBackPressed()无法正常工作。如何使用它? - Shyamaly Lakhadive

5

由于setTargetFragment已被废弃。您可以使用setFragmentResultListener

FragmentA

setFragmentResultListener("KEY") { reqKey, bundle ->
    if (reqKey == "KEY")
    {
        val result = bundle.getString("RESULT")
        Toast.makeText(requireContext(), "Result: $result", Toast.LENGTH_LONG).show()
    }
}

在FragmentB中:
val resultBundle = Bundle().apply { putString("RESULT", "result from FragmentB") }
setFragmentResult("KEY", resultBundle)

1

请为我工作。

在 FragmentB 中创建如下的接口回调:

private FragmentCallBacks fragmentCallBacks;

public interface FragmentCallBacks{
    void onCallBack(String data);
}

public void setFragmentCallBacks(FragmentCallBacks fragmentCallBacks) {
    this.fragmentCallBacks = fragmentCallBacks;
}

//onDestroy add this code
@Override
public void onDestroy() {
    super.onDestroy();
    fragmentCallBacks.onCallBack("This data from FragmentB");
}

在 FragmentA 中添加以下代码。
FragmentB fragment = new FragmentB();
replaceFragment(fragment, "TAG");
fragment.setFragmentCallBacks(data -> {
    //do something here with your data
});

public void replaceFragment(Fragment fragment, String tag) {
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.frameLayout, fragment);
    fragmentTransaction.addToBackStack(tag);
    fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
    fragmentTransaction.commit();
}

我希望这可以帮助你。


-1

FragmentA 通过使用 replace 调用 FragmentB

getFragmentManager!!.beginTransaction().replace(R.id.frame, fragmentB, tag).addToBackStack(null).commit()

然后 FragmentB 按下:

fragmentManager.popBackStack()

FragmentAoverride fun onViewCreated() 中尝试监听:

fragmentManager!!.addOnBackStackChangedListener {
  if (fragmentManager!!.backStackEntryCount == 0) {
           // Here your code
  }
}

这如何回答将数据传递给前一个片段的问题? - Tayyab Mazhar

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