ViewPager关联Fragment用Bundle传值出现No view found异常如何解决
错误诱因
你当前遇到的No view found for fragment one异常,核心原因是你在发送端Fragment中直接通过Fragment事务(add/replace)手动创建、挂载接收端Fragment:
- ViewPager中的所有Fragment由配套的PagerAdapter统一管理,自动挂载到ViewPager内部的专属容器,你手动调用Fragment事务操作时,传入的容器ID不属于ViewPager的内部容器,系统找不到对应视图就会抛出该异常
- 你手动new出来的接收端Fragment实例,和ViewPager中已经加载的目标Fragment不是同一个实例,就算不报错,数据也无法正常传递到正在展示的目标页面
解决方法
以下是适配TabLayout+ViewPager架构的Fragment数据互通方案,按推荐优先级排序:
方案1:使用共享ViewModel(优先推荐)
基于宿主Activity创建共享ViewModel,所有依附于该Activity的Fragment都可以获取到同一个ViewModel实例,直接通过ViewModel读写公共数据,无需跨Fragment持有引用,也不会触发生命周期异常。
示例代码:
- 定义共享ViewModel
class SharedViewModel : ViewModel() { // 定义需要传递的数据,用LiveData可自动观察变化 val sharedData = MutableLiveData<String>() }
- 发送端Fragment存数据
// 注意ViewModel要和宿主Activity绑定,不要和当前Fragment绑定 val sharedViewModel = ViewModelProvider(requireActivity())[SharedViewModel::class.java] sharedViewModel.sharedData.postValue("需要传递的内容")
- 接收端Fragment取数据
val sharedViewModel = ViewModelProvider(requireActivity())[SharedViewModel::class.java] sharedViewModel.sharedData.observe(viewLifecycleOwner) { data -> // 收到数据后做对应处理 }
方案2:通过宿主Activity中转
在宿主Activity中定义数据传递接口,发送端将数据传给Activity后,由Activity从PagerAdapter中获取ViewPager已加载的目标Fragment实例,再做数据传递:
- 宿主Activity定义接口
public interface DataTransferListener { void sendDataToTarget(String data); }
- 发送端Fragment调用接口
// 宿主Activity实现上述接口 ((DataTransferListener) requireActivity()).sendDataToTarget("要传递的数据");
- 宿主Activity拿到数据后,从PagerAdapter中获取已存在的目标Fragment实例,调用其公共方法传值,禁止手动new新的Fragment实例。
方案3:EventBus事件总线(适合复杂跨页面通信)
如果业务场景通信逻辑复杂,可引入EventBus组件,发送端发送事件,接收端注册监听事件即可,无需持有对方引用,注意要在生命周期中做好注册/反注册操作。
内容的提问来源于stack exchange,提问作者Fakhar Ullah
相关产品推荐
相关产品推荐

