You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Fragment 2的数据传递至Activity而非Fragment 1?

问题描述

页面跳转路径:

Activity -> Fragment 1 -> Fragment 2

需要将Fragment 2的数据传递至Activity。已创建PassDataInterface并在Fragment 2的构造方法中传入,但Fragment 1作为调用Fragment 2的发起方实现了该接口,导致Activity实现的接口方法从未被调用。

代码文件

MainActivity.kt

class MainActivity : AppCompatActivity(), PassDataInterface {

    private val name = "Sagar"
    private lateinit var fragmentView: FragmentContainerView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        fragmentView = findViewById(R.id.fragmentView)
        val bundle = Bundle()
        bundle.putString("name",name)
        val fragment = BlankFragment()
        fragment.arguments = bundle
        supportFragmentManager.beginTransaction().add(R.id.fragmentView, fragment).commit()
    }

    override fun onPassData(title: String) {
        println("Activity")
        setTitle(title)
    }
}

BlankFragment.kt(Fragment 1)

class BlankFragment : Fragment(),PassDataInterface {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_blank, container, false)
        val tv = view.findViewById<TextView>(R.id.tv)
        val btn = view.findViewById<Button>(R.id.btn)
        val name: String = arguments?.getString("name") as String
        btn.setOnClickListener {
            val bundle = Bundle()
            bundle.putString("name",name)
            val fragment2 = BlankFragment2(this)
            fragment2.arguments = bundle
            activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.fragmentView,fragment2)?.addToBackStack(null)?.commit()
        }
        tv.setText(name)
        return view
    }

    override fun onPassData(title: String) {
        println("Fragment 1")
    }

}

BlankFragment2.kt(Fragment 2)

class BlankFragment2(val passDataInterface: PassDataInterface): Fragment() {

  override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup ? ,
    savedInstanceState : Bundle ?
  ): View ? {
    // Inflate the layout for this fragment
    passDataInterface.onPassData("Fragment 2")
    val view = inflater.inflate(R.layout.fragment_blank2, container, false)
    val text = arguments ? .getString("name") as String
    val b2 = view.findViewById < TextView > (R.id.b2)
    val btnDownload = view.findViewById < Button > (R.id.btnDownload)
    if (checkSelfPermission(requireContext(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
      requestPermissions(arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
    }

    b2.text = text
    return view
  }

}

当前输出

Fragment 1

期望输出

Activity

解决方案

方法一:直接传递Activity的接口实例给Fragment 2

在BlankFragment创建Fragment2时,不要传入自身的接口实现,而是传入Activity的实例(因为Activity已经实现了PassDataInterface):

修改BlankFragment中的点击事件代码:

btn.setOnClickListener {
    val bundle = Bundle()
    bundle.putString("name",name)
    // 强转Activity为PassDataInterface并传入Fragment2
    val fragment2 = BlankFragment2(activity as PassDataInterface)
    fragment2.arguments = bundle
    activity?.supportFragmentManager?.beginTransaction()?.replace(R.id.fragmentView,fragment2)?.addToBackStack(null)?.commit()
}

修改后,Fragment2调用passDataInterface.onPassData()时,会直接触发Activity的实现方法,输出"Activity"。

方法二:让Fragment1转发数据到Activity

保留当前Fragment2传入Fragment1的逻辑,修改Fragment1的onPassData方法,将数据转发给Activity:

修改BlankFragment的onPassData方法:

override fun onPassData(title: String) {
    // 调用Activity的接口方法完成转发
    (activity as PassDataInterface).onPassData(title)
}

这样Fragment2调用Fragment1的接口方法后,Fragment1会把数据传递给Activity,最终输出"Activity"。

方法三:使用ViewModel(推荐的组件化方案)

跨Fragment和Activity传递数据时,ViewModel是更健壮的选择,无需依赖接口传递,避免强转和生命周期问题:

  1. 创建共享ViewModel:
class SharedViewModel : ViewModel() {
    val dataLiveData = MutableLiveData<String>()
}
  1. 在MainActivity中观察LiveData:
class MainActivity : AppCompatActivity() {
    private val sharedViewModel: SharedViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // ... 原有初始化代码

        sharedViewModel.dataLiveData.observe(this) { title ->
            println("Activity")
            setTitle(title)
        }
    }
}
  1. 在BlankFragment2中获取ViewModel并发送数据:
class BlankFragment2 : Fragment() {
    private val sharedViewModel: SharedViewModel by activityViewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // 发送数据到ViewModel
        sharedViewModel.dataLiveData.postValue("Fragment 2")
        
        // ... 原有视图初始化代码
        val view = inflater.inflate(R.layout.fragment_blank2, container, false)
        // ... 后续代码
        return view
    }
}

这种方式无需定义PassDataInterface,利用Jetpack组件的生命周期感知能力,更符合Android架构规范。


内容的提问来源于stack exchange,提问作者user20088323

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 02:35:19