如何在TabLayout中通过接口实现两个Fragment之间的数据传递
实现方案
方案1:使用共享ViewModel(官方推荐,低耦合)
这是谷歌官方推荐的同Activity下Fragment通信方案,不需要Fragment之间互相持有引用,耦合度极低。
步骤1:创建共享ViewModel类
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel class SharedViewModel : ViewModel() { // 定义可观察的字符串LiveData val sendText = MutableLiveData<String>() }
步骤2:第一个Fragment(带按钮的Fragment)发送数据
在按钮的点击事件里给ViewModel的LiveData设值:
// 第一个Fragment的onViewCreated方法内 val viewModel = ViewModelProvider(requireActivity())[SharedViewModel::class.java] yourButtonId.setOnClickListener { val needSendStr = "要传递的文本内容" viewModel.sendText.postValue(needSendStr) }
步骤3:第二个Fragment接收数据并展示到TextView
在第二个Fragment里观察LiveData的变化,收到数据后直接更新TextView:
// 第二个Fragment的onViewCreated方法内 val viewModel = ViewModelProvider(requireActivity())[SharedViewModel::class.java] val targetTextView = view.findViewById<TextView>(R.id.your_textview_id) viewModel.sendText.observe(viewLifecycleOwner) { text -> text?.let { targetTextView.text = it } }
注意:获取ViewModel时要绑定宿主Activity,不要绑定Fragment实例,否则两个Fragment会拿到不同的ViewModel对象,无法实现数据共享
方案2:接口回调法
如果你不想引入ViewModel组件,可以用接口回调通过宿主Activity中转数据。
步骤1:定义回调接口
interface OnTextSendListener { fun sendText(text: String) }
步骤2:宿主Activity实现该接口
class YourTabHostActivity : AppCompatActivity(), OnTextSendListener { // 初始化Tab和Fragment时保存第二个Fragment的引用 private var secondFragment: SecondFragment? = null override fun sendText(text: String) { secondFragment?.updateDisplayText(text) } }
步骤3:第一个Fragment触发回调
// 第一个Fragment的按钮点击事件内 yourButtonId.setOnClickListener { val sendStr = "要传递的文本内容" (requireActivity() as OnTextSendListener).sendText(sendStr) }
步骤4:第二个Fragment新增更新UI的公开方法
// 第二个Fragment内新增方法 fun updateDisplayText(text: String) { view?.findViewById<TextView>(R.id.your_textview_id)?.text = text }
注意:如果点击按钮时第二个Fragment还未完成初始化,你可以在Activity中先暂存要传递的字符串,等第二个Fragment的onResume生命周期触发后再调用更新方法,避免空指针异常。
内容的提问来源于stack exchange,提问作者Zubair Hussain
相关产品推荐
相关产品推荐

