MvvmCross:如何实现ViewPager内Fragment中TextView的数据绑定?
我来帮你搞定这个MvvmCross环境下ViewPager Fragment的数据绑定问题,咱们一步步排查几个容易踩坑的地方:
1. Adapter里的类名笔误
你写的DetailPagerAdapter类,构造函数居然写成了SectionsPagerAdapter,这明显是手滑了,会导致编译错误或者Adapter压根初始化不了:
错误代码片段:
public SectionsPagerAdapter(Android.Support.V4.App.FragmentManager fm) : base(fm)
修复成这样:
public DetailPagerAdapter(Android.Support.V4.App.FragmentManager fm) : base(fm)
2. Fragment实例化方式错了(这是核心问题!)
你直接用new UCAboutFragment()创建Fragment,这种原生Android的创建方式,MvvmCross根本管不到,导致AboutDetailViewModel的Prepare方法不会被调用,ViewModel和Fragment也没法正确关联,绑定自然就失效了。
MvvmCross有自己的Fragment创建机制,得用框架提供的方法,还要把父ViewModel的参数传进去(毕竟你的AboutDetailViewModel是继承MvxViewModel<DetailViewModel>,需要接收父ViewModel当参数)。
具体修复步骤:
第一步:修改Adapter的addFragment方法,用MvvmCross创建Fragment
把原来硬new Fragment的逻辑改成框架创建的方式:
private void AddFragment<TFragment, TViewModel>(string title, TViewModel parameter) where TFragment : IMvxFragment where TViewModel : IMvxViewModel { var fragment = Mvx.IoCProvider.Resolve<IMvxFragmentCreator>().CreateFragment<TFragment, TViewModel>(parameter); mFragmentList.Add(fragment as Android.Support.V4.App.Fragment); mFragmentTitleList.Add(title); }
第二步:修改Adapter构造函数,接收父ViewModel参数
因为子Fragment的ViewModel需要父DetailFragment的ViewModel当参数,所以Adapter得能拿到这个参数:
// 调整构造函数,加入父ViewModel参数 public DetailPagerAdapter(Android.Support.V4.App.FragmentManager fm, DetailViewModel parentViewModel) : base(fm) { mFragmentList = new List<Android.Support.V4.App.Fragment>(); // 用修改后的AddFragment方法创建子Fragment,传递父ViewModel AddFragment<UCAboutFragment, AboutDetailViewModel>("About", parentViewModel); AddFragment<UCServicesFragment, YourServicesViewModel>("Services", parentViewModel); // 替换成你的Services对应的ViewModel AddFragment<UCInsuranceFragment, YourInsuranceViewModel>("Insurance", parentViewModel); // 替换成你的Insurance对应的ViewModel }
第三步:在DetailFragment里初始化Adapter时传参
从DetailFragment自己的ViewModel里拿到实例,传给Adapter:
// 先获取当前DetailFragment的ViewModel var parentVm = (DetailViewModel)ViewModel; // 初始化Adapter时把父ViewModel传进去 DetailPagerAdapter pageAdapter = new DetailPagerAdapter(ChildFragmentManager, parentVm); ViewPager pager = thisView.FindViewById<ViewPager>(Resource.Id.viewpager); pager.Adapter = pageAdapter; TabLayout tabLayout = thisView.FindViewById<TabLayout>(Resource.Id.tabs); tabLayout.SetupWithViewPager(pager);
3. ViewModel的属性通知是对的
你的AboutDetailViewModel已经用[AddINotifyPropertyChangedInterface]和RaisePropertyChanged正确实现了属性变更通知,这部分没问题,只要Prepare方法能被调用,AboutDetail的值就能正确同步到TextView。
4. 布局绑定没毛病
你的about_fragment.axml里的绑定代码是正确的:
local:MvxBind="Text AboutDetail"
只要ViewModel和Fragment关联上,这个绑定就能生效。
最后再检查俩小细节
- 确保你的项目已经正确配置了MvvmCross的绑定环境(比如Setup类里初始化了绑定逻辑)。
- 核对Fragment的布局ID:
UCAboutFragment里FragmentId返回的是Resource.Layout.fragment_details_about,要确保这个ID对应的布局就是你提供的about_fragment.axml,别搞混了文件名。
按照这些步骤改完,ViewPager里的Fragment应该就能正确绑定ViewModel的属性啦!
内容的提问来源于stack exchange,提问作者Chanki

